@@ -201,8 +201,10 @@ struct BCECmp {
201201// (see canSplit()).
202202class BCECmpBlock {
203203 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)) {}
206208
207209 const BCEAtom &Lhs () const { return Cmp.Lhs ; }
208210 const BCEAtom &Rhs () const { return Cmp.Rhs ; }
@@ -219,8 +221,7 @@ class BCECmpBlock {
219221 // be sunk below this instruction. By doing this, we know we can separate the
220222 // BCE-cmp-block instructions from the non-BCE-cmp-block instructions in the
221223 // block.
222- bool canSinkBCECmpInst (const Instruction *, DenseSet<const Instruction *> &,
223- AliasAnalysis &AA) const ;
224+ bool canSinkBCECmpInst (const Instruction *, AliasAnalysis &AA) const ;
224225
225226 // We can separate the BCE-cmp-block instructions and the non-BCE-cmp-block
226227 // instructions. Split the old block and move all non-BCE-cmp-insts into the
@@ -229,8 +230,8 @@ class BCECmpBlock {
229230
230231 // The basic block where this comparison happens.
231232 BasicBlock *BB;
232- // The terminating branch.
233- BranchInst *BranchI ;
233+ // Instructions relating to the BCECmp and branch.
234+ InstructionSet BlockInsts ;
234235 // The block requires splitting.
235236 bool RequireSplit = false ;
236237
@@ -239,7 +240,6 @@ class BCECmpBlock {
239240};
240241
241242bool BCECmpBlock::canSinkBCECmpInst (const Instruction *Inst,
242- DenseSet<const Instruction *> &BlockInsts,
243243 AliasAnalysis &AA) const {
244244 // If this instruction may clobber the loads and is in middle of the BCE cmp
245245 // block instructions, then bail for now.
@@ -263,15 +263,11 @@ bool BCECmpBlock::canSinkBCECmpInst(const Instruction *Inst,
263263}
264264
265265void 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});
269266 llvm::SmallVector<Instruction *, 4 > OtherInsts;
270267 for (Instruction &Inst : *BB) {
271268 if (BlockInsts.count (&Inst))
272269 continue ;
273- assert (canSinkBCECmpInst (&Inst, BlockInsts, AA) &&
274- " Split unsplittable block" );
270+ assert (canSinkBCECmpInst (&Inst, AA) && " Split unsplittable block" );
275271 // This is a non-BCE-cmp-block instruction. And it can be separated
276272 // from the BCE-cmp-block instruction.
277273 OtherInsts.push_back (&Inst);
@@ -284,23 +280,16 @@ void BCECmpBlock::split(BasicBlock *NewParent, AliasAnalysis &AA) const {
284280}
285281
286282bool 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});
290283 for (Instruction &Inst : *BB) {
291284 if (!BlockInsts.count (&Inst)) {
292- if (!canSinkBCECmpInst (&Inst, BlockInsts, AA))
285+ if (!canSinkBCECmpInst (&Inst, AA))
293286 return false ;
294287 }
295288 }
296289 return true ;
297290}
298291
299292bool 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});
304293 // TODO(courbet): Can we allow some other things ? This is very conservative.
305294 // We might be able to get away with anything does not have any side
306295 // effects outside of the basic block.
@@ -351,37 +340,41 @@ Optional<BCECmpBlock> visitCmpBlock(Value *const Val, BasicBlock *const Block,
351340 auto *const BranchI = dyn_cast<BranchInst>(Block->getTerminator ());
352341 if (!BranchI) return None;
353342 LLVM_DEBUG (dbgs () << " branch\n " );
343+ Value *Cond;
344+ ICmpInst::Predicate ExpectedPredicate;
354345 if (BranchI->isUnconditional ()) {
355346 // In this case, we expect an incoming value which is the result of the
356347 // comparison. This is the last link in the chain of comparisons (note
357348 // that this does not mean that this is the last incoming value, blocks
358349 // 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;
366352 } else {
367353 // In this case, we expect a constant incoming value (the comparison is
368354 // chained).
369355 const auto *const Const = cast<ConstantInt>(Val);
370356 LLVM_DEBUG (dbgs () << " const\n " );
371- if (!Const->isZero ()) return {} ;
357+ if (!Const->isZero ()) return None ;
372358 LLVM_DEBUG (dbgs () << " false\n " );
373- auto *const CmpI = dyn_cast<ICmpInst>(BranchI->getCondition ());
374- if (!CmpI) return {};
375- LLVM_DEBUG (dbgs () << " icmp\n " );
376359 assert (BranchI->getNumSuccessors () == 2 && " expecting a cond branch" );
377360 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;
384364 }
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);
385378}
386379
387380static inline void enqueueBlock (std::vector<BCECmpBlock> &Comparisons,
0 commit comments