@@ -201,8 +201,10 @@ struct BCECmp {
201
201
// (see canSplit()).
202
202
class BCECmpBlock {
203
203
public:
204
- BCECmpBlock (BCECmp Cmp, BasicBlock *BB, BranchInst *BranchI)
205
- : BB(BB), BranchI(BranchI), Cmp(std::move(Cmp)) {}
204
+ typedef SmallDenseSet<const Instruction *, 8 > InstructionSet;
205
+
206
+ BCECmpBlock (BCECmp Cmp, BasicBlock *BB, InstructionSet BlockInsts)
207
+ : BB(BB), BlockInsts(std::move(BlockInsts)), Cmp(std::move(Cmp)) {}
206
208
207
209
const BCEAtom &Lhs () const { return Cmp.Lhs ; }
208
210
const BCEAtom &Rhs () const { return Cmp.Rhs ; }
@@ -219,8 +221,7 @@ class BCECmpBlock {
219
221
// be sunk below this instruction. By doing this, we know we can separate the
220
222
// BCE-cmp-block instructions from the non-BCE-cmp-block instructions in the
221
223
// block.
222
- bool canSinkBCECmpInst (const Instruction *, DenseSet<const Instruction *> &,
223
- AliasAnalysis &AA) const ;
224
+ bool canSinkBCECmpInst (const Instruction *, AliasAnalysis &AA) const ;
224
225
225
226
// We can separate the BCE-cmp-block instructions and the non-BCE-cmp-block
226
227
// instructions. Split the old block and move all non-BCE-cmp-insts into the
@@ -229,8 +230,8 @@ class BCECmpBlock {
229
230
230
231
// The basic block where this comparison happens.
231
232
BasicBlock *BB;
232
- // The terminating branch.
233
- BranchInst *BranchI ;
233
+ // Instructions relating to the BCECmp and branch.
234
+ InstructionSet BlockInsts ;
234
235
// The block requires splitting.
235
236
bool RequireSplit = false ;
236
237
@@ -239,7 +240,6 @@ class BCECmpBlock {
239
240
};
240
241
241
242
bool BCECmpBlock::canSinkBCECmpInst (const Instruction *Inst,
242
- DenseSet<const Instruction *> &BlockInsts,
243
243
AliasAnalysis &AA) const {
244
244
// If this instruction may clobber the loads and is in middle of the BCE cmp
245
245
// block instructions, then bail for now.
@@ -263,15 +263,11 @@ bool BCECmpBlock::canSinkBCECmpInst(const Instruction *Inst,
263
263
}
264
264
265
265
void BCECmpBlock::split (BasicBlock *NewParent, AliasAnalysis &AA) const {
266
- DenseSet<const Instruction *> BlockInsts (
267
- {Cmp.Lhs .GEP , Cmp.Rhs .GEP , Cmp.Lhs .LoadI , Cmp.Rhs .LoadI , Cmp.CmpI ,
268
- BranchI});
269
266
llvm::SmallVector<Instruction *, 4 > OtherInsts;
270
267
for (Instruction &Inst : *BB) {
271
268
if (BlockInsts.count (&Inst))
272
269
continue ;
273
- assert (canSinkBCECmpInst (&Inst, BlockInsts, AA) &&
274
- " Split unsplittable block" );
270
+ assert (canSinkBCECmpInst (&Inst, AA) && " Split unsplittable block" );
275
271
// This is a non-BCE-cmp-block instruction. And it can be separated
276
272
// from the BCE-cmp-block instruction.
277
273
OtherInsts.push_back (&Inst);
@@ -284,23 +280,16 @@ void BCECmpBlock::split(BasicBlock *NewParent, AliasAnalysis &AA) const {
284
280
}
285
281
286
282
bool BCECmpBlock::canSplit (AliasAnalysis &AA) const {
287
- DenseSet<const Instruction *> BlockInsts (
288
- {Cmp.Lhs .GEP , Cmp.Rhs .GEP , Cmp.Lhs .LoadI , Cmp.Rhs .LoadI , Cmp.CmpI ,
289
- BranchI});
290
283
for (Instruction &Inst : *BB) {
291
284
if (!BlockInsts.count (&Inst)) {
292
- if (!canSinkBCECmpInst (&Inst, BlockInsts, AA))
285
+ if (!canSinkBCECmpInst (&Inst, AA))
293
286
return false ;
294
287
}
295
288
}
296
289
return true ;
297
290
}
298
291
299
292
bool BCECmpBlock::doesOtherWork () const {
300
- // All the instructions we care about in the BCE cmp block.
301
- DenseSet<const Instruction *> BlockInsts (
302
- {Cmp.Lhs .GEP , Cmp.Rhs .GEP , Cmp.Lhs .LoadI , Cmp.Rhs .LoadI , Cmp.CmpI ,
303
- BranchI});
304
293
// TODO(courbet): Can we allow some other things ? This is very conservative.
305
294
// We might be able to get away with anything does not have any side
306
295
// effects outside of the basic block.
@@ -351,37 +340,41 @@ Optional<BCECmpBlock> visitCmpBlock(Value *const Val, BasicBlock *const Block,
351
340
auto *const BranchI = dyn_cast<BranchInst>(Block->getTerminator ());
352
341
if (!BranchI) return None;
353
342
LLVM_DEBUG (dbgs () << " branch\n " );
343
+ Value *Cond;
344
+ ICmpInst::Predicate ExpectedPredicate;
354
345
if (BranchI->isUnconditional ()) {
355
346
// In this case, we expect an incoming value which is the result of the
356
347
// comparison. This is the last link in the chain of comparisons (note
357
348
// that this does not mean that this is the last incoming value, blocks
358
349
// can be reordered).
359
- auto *const CmpI = dyn_cast<ICmpInst>(Val);
360
- if (!CmpI) return None;
361
- LLVM_DEBUG (dbgs () << " icmp\n " );
362
- Optional<BCECmp> Result = visitICmp (CmpI, ICmpInst::ICMP_EQ, BaseId);
363
- if (!Result)
364
- return None;
365
- return BCECmpBlock (std::move (*Result), Block, BranchI);
350
+ Cond = Val;
351
+ ExpectedPredicate = ICmpInst::ICMP_EQ;
366
352
} else {
367
353
// In this case, we expect a constant incoming value (the comparison is
368
354
// chained).
369
355
const auto *const Const = cast<ConstantInt>(Val);
370
356
LLVM_DEBUG (dbgs () << " const\n " );
371
- if (!Const->isZero ()) return {} ;
357
+ if (!Const->isZero ()) return None ;
372
358
LLVM_DEBUG (dbgs () << " false\n " );
373
- auto *const CmpI = dyn_cast<ICmpInst>(BranchI->getCondition ());
374
- if (!CmpI) return {};
375
- LLVM_DEBUG (dbgs () << " icmp\n " );
376
359
assert (BranchI->getNumSuccessors () == 2 && " expecting a cond branch" );
377
360
BasicBlock *const FalseBlock = BranchI->getSuccessor (1 );
378
- Optional<BCECmp> Result = visitICmp (
379
- CmpI, FalseBlock == PhiBlock ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE,
380
- BaseId);
381
- if (!Result)
382
- return None;
383
- return BCECmpBlock (std::move (*Result), Block, BranchI);
361
+ Cond = BranchI->getCondition ();
362
+ ExpectedPredicate =
363
+ FalseBlock == PhiBlock ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE;
384
364
}
365
+
366
+ auto *CmpI = dyn_cast<ICmpInst>(Cond);
367
+ if (!CmpI) return None;
368
+ LLVM_DEBUG (dbgs () << " icmp\n " );
369
+
370
+ Optional<BCECmp> Result = visitICmp (CmpI, ExpectedPredicate, BaseId);
371
+ if (!Result)
372
+ return None;
373
+
374
+ BCECmpBlock::InstructionSet BlockInsts (
375
+ {Result->Lhs .GEP , Result->Rhs .GEP , Result->Lhs .LoadI , Result->Rhs .LoadI ,
376
+ Result->CmpI , BranchI});
377
+ return BCECmpBlock (std::move (*Result), Block, BlockInsts);
385
378
}
386
379
387
380
static inline void enqueueBlock (std::vector<BCECmpBlock> &Comparisons,
0 commit comments