19
19
// - Code size is smaller, both because jumps are removed and because the
20
20
// encoding of a 2*n byte compare is smaller than that of two n-byte
21
21
// compares.
22
- //
22
+
23
23
// ===----------------------------------------------------------------------===//
24
24
25
- #include " llvm/ADT/APInt.h"
26
- #include " llvm/ADT/ArrayRef.h"
25
+ #include < algorithm>
26
+ #include < numeric>
27
+ #include < utility>
28
+ #include < vector>
29
+ #include " llvm/ADT/APSInt.h"
27
30
#include " llvm/Analysis/Loads.h"
28
31
#include " llvm/Analysis/TargetLibraryInfo.h"
29
32
#include " llvm/Analysis/TargetTransformInfo.h"
30
- #include " llvm/IR/BasicBlock.h"
31
- #include " llvm/IR/Constants.h"
32
- #include " llvm/IR/DataLayout.h"
33
33
#include " llvm/IR/Function.h"
34
34
#include " llvm/IR/IRBuilder.h"
35
- #include " llvm/IR/Instruction.h"
36
- #include " llvm/IR/Instructions.h"
37
- #include " llvm/IR/Module.h"
38
- #include " llvm/IR/PassManager.h"
39
- #include " llvm/IR/Type.h"
40
- #include " llvm/IR/Value.h"
35
+ #include " llvm/IR/IntrinsicInst.h"
41
36
#include " llvm/Pass.h"
42
- #include " llvm/Support/Casting.h"
43
- #include " llvm/Support/Debug.h"
44
- #include " llvm/Support/raw_ostream.h"
45
37
#include " llvm/Transforms/Scalar.h"
46
38
#include " llvm/Transforms/Utils/BuildLibCalls.h"
47
- #include < algorithm>
48
- #include < cassert>
49
- #include < cstddef>
50
- #include < numeric>
51
- #include < utility>
52
- #include < vector>
53
39
54
40
using namespace llvm ;
55
41
56
- #define DEBUG_TYPE " mergeicmps"
57
-
58
42
namespace {
59
43
44
+ #define DEBUG_TYPE " mergeicmps"
45
+
60
46
// A BCE atom.
61
47
struct BCEAtom {
62
- BCEAtom () = default ;
48
+ BCEAtom () : GEP( nullptr ), LoadI( nullptr ), Offset() {}
63
49
64
50
const Value *Base () const { return GEP ? GEP->getPointerOperand () : nullptr ; }
65
51
@@ -81,17 +67,15 @@ struct BCEAtom {
81
67
return NameCmp < 0 ;
82
68
}
83
69
84
- GetElementPtrInst *GEP = nullptr ;
85
- LoadInst *LoadI = nullptr ;
70
+ GetElementPtrInst *GEP;
71
+ LoadInst *LoadI;
86
72
APInt Offset;
87
73
};
88
74
89
- } // end anonymous namespace
90
-
91
75
// If this value is a load from a constant offset w.r.t. a base address, and
92
76
// there are no othe rusers of the load or address, returns the base address and
93
77
// the offset.
94
- static BCEAtom visitICmpLoadOperand (Value *const Val) {
78
+ BCEAtom visitICmpLoadOperand (Value *const Val) {
95
79
BCEAtom Result;
96
80
if (auto *const LoadI = dyn_cast<LoadInst>(Val)) {
97
81
DEBUG (dbgs () << " load\n " );
@@ -127,16 +111,14 @@ static BCEAtom visitICmpLoadOperand(Value *const Val) {
127
111
return Result;
128
112
}
129
113
130
- namespace {
131
-
132
114
// A basic block with a comparison between two BCE atoms.
133
115
// Note: the terminology is misleading: the comparison is symmetric, so there
134
116
// is no real {l/r}hs. What we want though is to have the same base on the
135
117
// left (resp. right), so that we can detect consecutive loads. To ensure this
136
118
// we put the smallest atom on the left.
137
119
class BCECmpBlock {
138
- public:
139
- BCECmpBlock () = default ;
120
+ public:
121
+ BCECmpBlock () {}
140
122
141
123
BCECmpBlock (BCEAtom L, BCEAtom R, int SizeBits)
142
124
: Lhs_(L), Rhs_(R), SizeBits_(SizeBits) {
@@ -166,21 +148,17 @@ class BCECmpBlock {
166
148
167
149
// The basic block where this comparison happens.
168
150
BasicBlock *BB = nullptr ;
169
-
170
151
// The ICMP for this comparison.
171
152
ICmpInst *CmpI = nullptr ;
172
-
173
153
// The terminating branch.
174
154
BranchInst *BranchI = nullptr ;
175
155
176
- private:
156
+ private:
177
157
BCEAtom Lhs_;
178
158
BCEAtom Rhs_;
179
159
int SizeBits_ = 0 ;
180
160
};
181
161
182
- } // end anonymous namespace
183
-
184
162
bool BCECmpBlock::doesOtherWork () const {
185
163
AssertConsistent ();
186
164
// TODO(courbet): Can we allow some other things ? This is very conservative.
@@ -205,8 +183,8 @@ bool BCECmpBlock::doesOtherWork() const {
205
183
206
184
// Visit the given comparison. If this is a comparison between two valid
207
185
// BCE atoms, returns the comparison.
208
- static BCECmpBlock visitICmp (const ICmpInst *const CmpI,
209
- const ICmpInst::Predicate ExpectedPredicate) {
186
+ BCECmpBlock visitICmp (const ICmpInst *const CmpI,
187
+ const ICmpInst::Predicate ExpectedPredicate) {
210
188
if (CmpI->getPredicate () == ExpectedPredicate) {
211
189
DEBUG (dbgs () << " cmp "
212
190
<< (ExpectedPredicate == ICmpInst::ICMP_EQ ? " eq" : " ne" )
@@ -223,8 +201,8 @@ static BCECmpBlock visitICmp(const ICmpInst *const CmpI,
223
201
224
202
// Visit the given comparison block. If this is a comparison between two valid
225
203
// BCE atoms, returns the comparison.
226
- static BCECmpBlock visitCmpBlock (Value *const Val, BasicBlock *const Block,
227
- const BasicBlock *const PhiBlock) {
204
+ BCECmpBlock visitCmpBlock (Value *const Val, BasicBlock *const Block,
205
+ const BasicBlock *const PhiBlock) {
228
206
if (Block->empty ()) return {};
229
207
auto *const BranchI = dyn_cast<BranchInst>(Block->getTerminator ());
230
208
if (!BranchI) return {};
@@ -262,11 +240,9 @@ static BCECmpBlock visitCmpBlock(Value *const Val, BasicBlock *const Block,
262
240
return {};
263
241
}
264
242
265
- namespace {
266
-
267
243
// A chain of comparisons.
268
244
class BCECmpChain {
269
- public:
245
+ public:
270
246
BCECmpChain (const std::vector<BasicBlock *> &Blocks, PHINode &Phi);
271
247
272
248
int size () const { return Comparisons_.size (); }
@@ -277,7 +253,7 @@ class BCECmpChain {
277
253
278
254
bool simplify (const TargetLibraryInfo *const TLI);
279
255
280
- private:
256
+ private:
281
257
static bool IsContiguous (const BCECmpBlock &First,
282
258
const BCECmpBlock &Second) {
283
259
return First.Lhs ().Base () == Second.Lhs ().Base () &&
@@ -295,13 +271,10 @@ class BCECmpChain {
295
271
296
272
PHINode &Phi_;
297
273
std::vector<BCECmpBlock> Comparisons_;
298
-
299
274
// The original entry block (before sorting);
300
275
BasicBlock *EntryBlock_;
301
276
};
302
277
303
- } // end anonymous namespace
304
-
305
278
BCECmpChain::BCECmpChain (const std::vector<BasicBlock *> &Blocks, PHINode &Phi)
306
279
: Phi_(Phi) {
307
280
// Now look inside blocks to check for BCE comparisons.
@@ -474,8 +447,7 @@ void BCECmpChain::mergeComparisons(ArrayRef<BCECmpBlock> Comparisons,
474
447
IRBuilder<> Builder (BB);
475
448
const auto &DL = Phi.getModule ()->getDataLayout ();
476
449
Value *const MemCmpCall = emitMemCmp (
477
- FirstComparison.Lhs ().GEP , FirstComparison.Rhs ().GEP ,
478
- ConstantInt::get (DL.getIntPtrType (Context), TotalSize),
450
+ FirstComparison.Lhs ().GEP , FirstComparison.Rhs ().GEP , ConstantInt::get (DL.getIntPtrType (Context), TotalSize),
479
451
Builder, DL, TLI);
480
452
Value *const MemCmpIsZero = Builder.CreateICmpEQ (
481
453
MemCmpCall, ConstantInt::get (Type::getInt32Ty (Context), 0 ));
@@ -532,9 +504,9 @@ void BCECmpChain::mergeComparisons(ArrayRef<BCECmpBlock> Comparisons,
532
504
}
533
505
}
534
506
535
- static std::vector<BasicBlock *> getOrderedBlocks (PHINode &Phi,
536
- BasicBlock *const LastBlock,
537
- int NumBlocks) {
507
+ std::vector<BasicBlock *> getOrderedBlocks (PHINode &Phi,
508
+ BasicBlock *const LastBlock,
509
+ int NumBlocks) {
538
510
// Walk up from the last block to find other blocks.
539
511
std::vector<BasicBlock *> Blocks (NumBlocks);
540
512
BasicBlock *CurBlock = LastBlock;
@@ -566,7 +538,7 @@ static std::vector<BasicBlock *> getOrderedBlocks(PHINode &Phi,
566
538
return Blocks;
567
539
}
568
540
569
- static bool processPhi (PHINode &Phi, const TargetLibraryInfo *const TLI) {
541
+ bool processPhi (PHINode &Phi, const TargetLibraryInfo *const TLI) {
570
542
DEBUG (dbgs () << " processPhi()\n " );
571
543
if (Phi.getNumIncomingValues () <= 1 ) {
572
544
DEBUG (dbgs () << " skip: only one incoming value in phi\n " );
@@ -621,10 +593,8 @@ static bool processPhi(PHINode &Phi, const TargetLibraryInfo *const TLI) {
621
593
return CmpChain.simplify (TLI);
622
594
}
623
595
624
- namespace {
625
-
626
596
class MergeICmps : public FunctionPass {
627
- public:
597
+ public:
628
598
static char ID;
629
599
630
600
MergeICmps () : FunctionPass(ID) {
@@ -639,18 +609,16 @@ class MergeICmps : public FunctionPass {
639
609
return !PA.areAllPreserved ();
640
610
}
641
611
612
+ private:
642
613
void getAnalysisUsage (AnalysisUsage &AU) const override {
643
614
AU.addRequired <TargetLibraryInfoWrapperPass>();
644
615
AU.addRequired <TargetTransformInfoWrapperPass>();
645
616
}
646
617
647
- private:
648
618
PreservedAnalyses runImpl (Function &F, const TargetLibraryInfo *TLI,
649
619
const TargetTransformInfo *TTI);
650
620
};
651
621
652
- } // end anonymous namespace
653
-
654
622
PreservedAnalyses MergeICmps::runImpl (Function &F, const TargetLibraryInfo *TLI,
655
623
const TargetTransformInfo *TTI) {
656
624
DEBUG (dbgs () << " MergeICmpsPass: " << F.getName () << " \n " );
@@ -672,8 +640,9 @@ PreservedAnalyses MergeICmps::runImpl(Function &F, const TargetLibraryInfo *TLI,
672
640
return PreservedAnalyses::all ();
673
641
}
674
642
675
- char MergeICmps::ID = 0 ;
643
+ } // namespace
676
644
645
+ char MergeICmps::ID = 0 ;
677
646
INITIALIZE_PASS_BEGIN (MergeICmps, " mergeicmps" ,
678
647
" Merge contiguous icmps into a memcmp" , false , false )
679
648
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
0 commit comments