1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
//===- LoopInstSimplify.cpp - Loop Instruction Simplification Pass --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass performs lightweight instruction simplification on loop bodies.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "loop-instsimplify"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;
STATISTIC(NumSimplified, "Number of redundant instructions simplified");
namespace {
class LoopInstSimplify : public LoopPass {
public:
static char ID; // Pass ID, replacement for typeid
LoopInstSimplify() : LoopPass(ID) {
initializeLoopInstSimplifyPass(*PassRegistry::getPassRegistry());
}
bool runOnLoop(Loop*, LPPassManager&);
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
AU.addRequired<LoopInfo>();
AU.addRequiredID(LoopSimplifyID);
AU.addPreservedID(LCSSAID);
}
};
}
char LoopInstSimplify::ID = 0;
INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify",
"Simplify instructions in loops", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
INITIALIZE_PASS_DEPENDENCY(LCSSA)
INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify",
"Simplify instructions in loops", false, false)
Pass* llvm::createLoopInstSimplifyPass() {
return new LoopInstSimplify();
}
bool LoopInstSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
LoopInfo *LI = &getAnalysis<LoopInfo>();
const TargetData *TD = getAnalysisIfAvailable<TargetData>();
SmallVector<BasicBlock*, 8> ExitBlocks;
L->getUniqueExitBlocks(ExitBlocks);
array_pod_sort(ExitBlocks.begin(), ExitBlocks.end());
SmallPtrSet<const Instruction*, 8> S1, S2, *ToSimplify = &S1, *Next = &S2;
SmallVector<BasicBlock*, 16> VisitStack;
SmallPtrSet<BasicBlock*, 32> Visited;
bool Changed = false;
bool LocalChanged;
do {
LocalChanged = false;
VisitStack.clear();
Visited.clear();
VisitStack.push_back(L->getHeader());
while (!VisitStack.empty()) {
BasicBlock *BB = VisitStack.back();
VisitStack.pop_back();
// Simplify instructions in the current basic block.
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
Instruction *I = BI++;
// The first time through the loop ToSimplify is empty and we try to
// simplify all instructions. On later iterations ToSimplify is not
// empty and we only bother simplifying instructions that are in it.
if (!ToSimplify->empty() && !ToSimplify->count(I))
continue;
// Don't bother simplifying unused instructions.
if (!I->use_empty()) {
Value *V = SimplifyInstruction(I, TD, DT);
if (V && LI->replacementPreservesLCSSAForm(I, V)) {
// Mark all uses for resimplification next time round the loop.
for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
UI != UE; ++UI)
Next->insert(cast<Instruction>(*UI));
I->replaceAllUsesWith(V);
LocalChanged = true;
++NumSimplified;
}
}
LocalChanged |= RecursivelyDeleteTriviallyDeadInstructions(I);
}
// Add all successors to the worklist, except for loop exit blocks.
for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE;
++SI) {
BasicBlock *SuccBB = *SI;
bool IsExitBlock = std::binary_search(ExitBlocks.begin(),
ExitBlocks.end(), SuccBB);
if (!IsExitBlock && Visited.insert(SuccBB))
VisitStack.push_back(SuccBB);
}
}
// Place the list of instructions to simplify on the next loop iteration
// into ToSimplify.
std::swap(ToSimplify, Next);
Next->clear();
Changed |= LocalChanged;
} while (LocalChanged);
return Changed;
}
|