1//===- ReduceUsingSimplifyCFG.h - Specialized Delta Pass ------------------===//
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 implements a function which calls the Generic Delta pass in order
10// to call SimplifyCFG on individual basic blocks.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ReduceUsingSimplifyCFG.h"
15#include "Utils.h"
16#include "llvm/Analysis/TargetTransformInfo.h"
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/Instructions.h"
19#include "llvm/Transforms/Utils/Local.h"
20
21using namespace llvm;
22
23void llvm::reduceUsingSimplifyCFGDeltaPass(Oracle &O,
24 ReducerWorkItem &WorkItem) {
25 Module &Program = WorkItem.getModule();
26 SmallVector<BasicBlock *, 16> ToSimplify;
27 for (auto &F : Program)
28 for (auto &BB : F)
29 if (!O.shouldKeep())
30 ToSimplify.push_back(Elt: &BB);
31 TargetTransformInfo TTI(Program.getDataLayout());
32 for (auto *BB : ToSimplify)
33 simplifyCFG(BB, TTI);
34}
35
36static void reduceConditionals(Oracle &O, ReducerWorkItem &WorkItem,
37 bool Direction) {
38 Module &M = WorkItem.getModule();
39
40 LLVMContext &Ctx = M.getContext();
41 ConstantInt *ConstValToSet =
42 Direction ? ConstantInt::getTrue(Context&: Ctx) : ConstantInt::getFalse(Context&: Ctx);
43
44 for (Function &F : M) {
45 if (F.isDeclaration())
46 continue;
47
48 SmallVector<BasicBlock *, 16> ToSimplify;
49
50 for (auto &BB : F) {
51 auto *BR = dyn_cast<CondBrInst>(Val: BB.getTerminator());
52 if (!BR || BR->getCondition() == ConstValToSet || O.shouldKeep())
53 continue;
54
55 BR->setCondition(ConstValToSet);
56 ToSimplify.push_back(Elt: &BB);
57 }
58
59 if (!ToSimplify.empty()) {
60 // TODO: Should probably leave MergeBlockIntoPredecessor for a separate
61 // reduction
62 simpleSimplifyCFG(F, BBs: ToSimplify);
63 }
64 }
65}
66
67void llvm::reduceConditionalsTrueDeltaPass(Oracle &O,
68 ReducerWorkItem &WorkItem) {
69 reduceConditionals(O, WorkItem, Direction: true);
70}
71
72void llvm::reduceConditionalsFalseDeltaPass(Oracle &O,
73 ReducerWorkItem &WorkItem) {
74 reduceConditionals(O, WorkItem, Direction: false);
75}
76
77void llvm::reduceUnconditionalBranchDeltaPass(Oracle &O,
78 ReducerWorkItem &WorkItem) {
79 Module &M = WorkItem.getModule();
80 LLVMContext &Ctx = M.getContext();
81
82 for (Function &F : M) {
83 if (F.isDeclaration())
84 continue;
85
86 SmallVector<BasicBlock *, 16> ToSimplify;
87
88 Type *RetTy = F.getReturnType();
89
90 for (auto &BB : F) {
91 auto *BR = dyn_cast<UncondBrInst>(Val: BB.getTerminator());
92 if (!BR)
93 continue;
94
95 if (O.shouldKeep())
96 continue;
97
98 BasicBlock *Succ = BR->getSuccessor();
99 Succ->removePredecessor(Pred: &BB, /*KeepOneInputPHIs=*/true);
100 BR->eraseFromParent();
101 ToSimplify.push_back(Elt: &BB);
102
103 if (RetTy->isVoidTy())
104 ReturnInst::Create(C&: Ctx, InsertAtEnd: &BB);
105 else
106 ReturnInst::Create(C&: Ctx, retVal: getDefaultValue(T: RetTy), InsertBefore: &BB);
107 }
108
109 if (!ToSimplify.empty())
110 simpleSimplifyCFG(F, BBs: ToSimplify);
111 }
112}
113