37 changes: 28 additions & 9 deletions llvm/lib/Transforms/Scalar/LowerConstantIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
Expand Down Expand Up @@ -50,7 +52,8 @@ static Value *lowerIsConstantIntrinsic(IntrinsicInst *II) {
}

static bool replaceConditionalBranchesOnConstant(Instruction *II,
Value *NewValue) {
Value *NewValue,
DomTreeUpdater *DTU) {
bool HasDeadBlocks = false;
SmallSetVector<Instruction *, 8> Worklist;
replaceAndRecursivelySimplify(II, NewValue, nullptr, nullptr, nullptr,
Expand Down Expand Up @@ -78,14 +81,21 @@ static bool replaceConditionalBranchesOnConstant(Instruction *II,
Other->removePredecessor(Source);
BI->eraseFromParent();
BranchInst::Create(Target, Source);
if (DTU)
DTU->applyUpdates({{DominatorTree::Delete, Source, Other}});
if (pred_empty(Other))
HasDeadBlocks = true;
}
}
return HasDeadBlocks;
}

static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo *TLI) {
static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo *TLI,
DominatorTree *DT) {
Optional<DomTreeUpdater> DTU;
if (DT)
DTU.emplace(DT, DomTreeUpdater::UpdateStrategy::Lazy);

bool HasDeadBlocks = false;
const auto &DL = F.getParent()->getDataLayout();
SmallVector<WeakTrackingVH, 8> Worklist;
Expand Down Expand Up @@ -128,19 +138,21 @@ static bool lowerConstantIntrinsics(Function &F, const TargetLibraryInfo *TLI) {
ObjectSizeIntrinsicsHandled++;
break;
}
HasDeadBlocks |= replaceConditionalBranchesOnConstant(II, NewValue);
HasDeadBlocks |= replaceConditionalBranchesOnConstant(
II, NewValue, DTU.hasValue() ? DTU.getPointer() : nullptr);
}
if (HasDeadBlocks)
removeUnreachableBlocks(F);
removeUnreachableBlocks(F, DTU.hasValue() ? DTU.getPointer() : nullptr);
return !Worklist.empty();
}

PreservedAnalyses
LowerConstantIntrinsicsPass::run(Function &F, FunctionAnalysisManager &AM) {
if (lowerConstantIntrinsics(F,
AM.getCachedResult<TargetLibraryAnalysis>(F))) {
if (lowerConstantIntrinsics(F, AM.getCachedResult<TargetLibraryAnalysis>(F),
AM.getCachedResult<DominatorTreeAnalysis>(F))) {
PreservedAnalyses PA;
PA.preserve<GlobalsAA>();
PA.preserve<DominatorTreeAnalysis>();
return PA;
}

Expand All @@ -163,18 +175,25 @@ class LowerConstantIntrinsics : public FunctionPass {
bool runOnFunction(Function &F) override {
auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
const TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI(F) : nullptr;
return lowerConstantIntrinsics(F, TLI);
DominatorTree *DT = nullptr;
if (auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
DT = &DTWP->getDomTree();
return lowerConstantIntrinsics(F, TLI, DT);
}

void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
}
};
} // namespace

char LowerConstantIntrinsics::ID = 0;
INITIALIZE_PASS(LowerConstantIntrinsics, "lower-constant-intrinsics",
"Lower constant intrinsics", false, false)
INITIALIZE_PASS_BEGIN(LowerConstantIntrinsics, "lower-constant-intrinsics",
"Lower constant intrinsics", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(LowerConstantIntrinsics, "lower-constant-intrinsics",
"Lower constant intrinsics", false, false)

FunctionPass *llvm::createLowerConstantIntrinsicsPass() {
return new LowerConstantIntrinsics();
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Utils/EscapeEnumerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ IRBuilder<> *EscapeEnumerator::Next() {
SmallVector<Value *, 16> Args;
for (unsigned I = Calls.size(); I != 0;) {
CallInst *CI = cast<CallInst>(Calls[--I]);
changeToInvokeAndSplitBasicBlock(CI, CleanupBB);
changeToInvokeAndSplitBasicBlock(CI, CleanupBB, DTU);
}

Builder.SetInsertPoint(RI);
Expand Down
12 changes: 8 additions & 4 deletions llvm/lib/Transforms/Utils/Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2122,15 +2122,16 @@ void llvm::changeToCall(InvokeInst *II, DomTreeUpdater *DTU) {
}

BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
BasicBlock *UnwindEdge) {
BasicBlock *UnwindEdge,
DomTreeUpdater *DTU) {
BasicBlock *BB = CI->getParent();

// Convert this function call into an invoke instruction. First, split the
// basic block.
BasicBlock *Split =
BB->splitBasicBlock(CI->getIterator(), CI->getName() + ".noexc");
BasicBlock *Split = SplitBlock(BB, CI, DTU, /*LI=*/nullptr, /*MSSAU*/ nullptr,
CI->getName() + ".noexc");

// Delete the unconditional branch inserted by splitBasicBlock
// Delete the unconditional branch inserted by SplitBlock
BB->getInstList().pop_back();

// Create the new invoke instruction.
Expand All @@ -2150,6 +2151,9 @@ BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
II->setCallingConv(CI->getCallingConv());
II->setAttributes(CI->getAttributes());

if (DTU)
DTU->applyUpdates({{DominatorTree::Insert, BB, UnwindEdge}});

// Make sure that anything using the call now uses the invoke! This also
// updates the CallGraph if present, because it uses a WeakTrackingVH.
CI->replaceAllUsesWith(II);
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/AArch64/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
; CHECK-NEXT: Shadow Stack GC Lowering
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Remove unreachable blocks from the CFG
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
; CHECK-NEXT: Branch Probability Analysis
Expand Down
3 changes: 0 additions & 3 deletions llvm/test/CodeGen/AMDGPU/opt-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@
; GCN-O1-NEXT: Dominator Tree Construction
; GCN-O1-NEXT: Float to int
; GCN-O1-NEXT: Lower constant intrinsics
; GCN-O1-NEXT: Dominator Tree Construction
; GCN-O1-NEXT: Natural Loop Information
; GCN-O1-NEXT: Canonicalize natural loops
; GCN-O1-NEXT: LCSSA Verifier
Expand Down Expand Up @@ -560,7 +559,6 @@
; GCN-O2-NEXT: Dominator Tree Construction
; GCN-O2-NEXT: Float to int
; GCN-O2-NEXT: Lower constant intrinsics
; GCN-O2-NEXT: Dominator Tree Construction
; GCN-O2-NEXT: Natural Loop Information
; GCN-O2-NEXT: Canonicalize natural loops
; GCN-O2-NEXT: LCSSA Verifier
Expand Down Expand Up @@ -924,7 +922,6 @@
; GCN-O3-NEXT: Dominator Tree Construction
; GCN-O3-NEXT: Float to int
; GCN-O3-NEXT: Lower constant intrinsics
; GCN-O3-NEXT: Dominator Tree Construction
; GCN-O3-NEXT: Natural Loop Information
; GCN-O3-NEXT: Canonicalize natural loops
; GCN-O3-NEXT: LCSSA Verifier
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/ARM/O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
; CHECK-NEXT: Shadow Stack GC Lowering
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Remove unreachable blocks from the CFG
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
; CHECK-NEXT: Branch Probability Analysis
Expand Down
1 change: 0 additions & 1 deletion llvm/test/CodeGen/X86/opt-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
; CHECK-NEXT: Shadow Stack GC Lowering
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Remove unreachable blocks from the CFG
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Post-Dominator Tree Construction
; CHECK-NEXT: Branch Probability Analysis
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Other/opt-O2-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,6 @@
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Float to int
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Canonicalize natural loops
; CHECK-NEXT: LCSSA Verifier
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Other/opt-O3-pipeline-enable-matrix.ll
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Float to int
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Lazy Branch Probability Analysis
; CHECK-NEXT: Lazy Block Frequency Analysis
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Other/opt-O3-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Float to int
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Canonicalize natural loops
; CHECK-NEXT: LCSSA Verifier
Expand Down
1 change: 0 additions & 1 deletion llvm/test/Other/opt-Os-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Float to int
; CHECK-NEXT: Lower constant intrinsics
; CHECK-NEXT: Dominator Tree Construction
; CHECK-NEXT: Natural Loop Information
; CHECK-NEXT: Canonicalize natural loops
; CHECK-NEXT: LCSSA Verifier
Expand Down