1 | //===- Utils.cpp - llvm-reduce utility functions --------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file contains some utility functions supporting llvm-reduce. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "Utils.h" |
14 | #include "llvm/IR/Constants.h" |
15 | #include "llvm/IR/GlobalAlias.h" |
16 | #include "llvm/IR/GlobalIFunc.h" |
17 | #include "llvm/Transforms/Utils/BasicBlockUtils.h" |
18 | #include "llvm/Transforms/Utils/Local.h" |
19 | |
20 | using namespace llvm; |
21 | |
22 | extern cl::OptionCategory LLVMReduceOptions; |
23 | |
24 | cl::opt<bool> llvm::Verbose("verbose" , |
25 | cl::desc("Print extra debugging information" ), |
26 | cl::init(Val: false), cl::cat(LLVMReduceOptions)); |
27 | |
28 | Value *llvm::getDefaultValue(Type *T) { |
29 | if (T->isVoidTy()) |
30 | return PoisonValue::get(T); |
31 | |
32 | if (auto *TET = dyn_cast<TargetExtType>(Val: T)) { |
33 | if (TET->hasProperty(Prop: TargetExtType::HasZeroInit)) |
34 | return ConstantTargetNone::get(T: TET); |
35 | return PoisonValue::get(T: TET); |
36 | } |
37 | |
38 | return Constant::getNullValue(Ty: T); |
39 | } |
40 | |
41 | bool llvm::hasAliasUse(Function &F) { |
42 | return any_of(Range: F.users(), P: [](User *U) { |
43 | return isa<GlobalAlias>(Val: U) || isa<GlobalIFunc>(Val: U); |
44 | }); |
45 | } |
46 | |
47 | void llvm::simpleSimplifyCFG(Function &F, ArrayRef<BasicBlock *> BBs, |
48 | bool FoldBlockIntoPredecessor) { |
49 | |
50 | for (BasicBlock *BB : BBs) { |
51 | ConstantFoldTerminator(BB); |
52 | if (FoldBlockIntoPredecessor) |
53 | MergeBlockIntoPredecessor(BB); |
54 | } |
55 | |
56 | // Remove unreachable blocks |
57 | // |
58 | // removeUnreachableBlocks can't be used here, it will turn various undefined |
59 | // behavior into unreachables, but llvm-reduce was the thing that generated |
60 | // the undefined behavior, and we don't want it to kill the entire program. |
61 | SmallPtrSet<BasicBlock *, 16> Visited(llvm::from_range, |
62 | depth_first(G: &F.getEntryBlock())); |
63 | |
64 | SmallVector<BasicBlock *, 16> Unreachable; |
65 | for (BasicBlock &BB : F) { |
66 | if (!Visited.count(Ptr: &BB)) |
67 | Unreachable.push_back(Elt: &BB); |
68 | } |
69 | |
70 | // The dead BB's may be in a dead cycle or otherwise have references to each |
71 | // other. Because of this, we have to drop all references first, then delete |
72 | // them all at once. |
73 | for (BasicBlock *BB : Unreachable) { |
74 | for (BasicBlock *Successor : successors(BB: &*BB)) |
75 | if (Visited.count(Ptr: Successor)) |
76 | Successor->removePredecessor(Pred: &*BB, /*KeepOneInputPHIs=*/true); |
77 | BB->dropAllReferences(); |
78 | } |
79 | |
80 | for (BasicBlock *BB : Unreachable) |
81 | BB->eraseFromParent(); |
82 | } |
83 | |