Fix logic related to isTriviallyDuplicatable.

In SILInstruction::isTriviallyDuplicatable():

- Make deallocating instructions trivially duplicatable. They are by
  any useful definition--duplicating an instruction does not imply
  reordering it. Tail duplication was already treating deallocations
  as duplicatable, but doing it inconsistently. Sometimes it checks
  isTriviallyDuplicatable, and sometimes it doesn't, which appears to
  have been an accident. Disallowing duplication of deallocations will
  cause severe performance regressions. Instead, consistently allow
  them to be duplicated, making tail duplication more powerful, which
  could expose other bugs.

- Do not duplicate on-stack AllocRefInst (without special
  consideration). This is a correctness fix that apparently was never
  exposed.

Fix SILLoop::canDuplicate():

- Handle isDeallocatingStack. It's not clear how we were avoiding an
  assertion before when a stack allocatable reference was confined to
  a loop--probably just by luck.

- Handle begin/end_access inside a loop. This is extremely important
  and probably prevented many loop optimizations from working with
  exclusivity.

Update LoopRotate canDuplicateOrMoveToPreheader(). This is NFC.
This commit is contained in:
Andrew Trick
2019-11-13 18:39:23 -08:00
parent cd3ada5abb
commit 71523642ce
4 changed files with 27 additions and 20 deletions

View File

@@ -70,6 +70,10 @@ canDuplicateOrMoveToPreheader(SILLoop *loop, SILBasicBlock *preheader,
invariants.insert(inst);
} else if (!inst->isTriviallyDuplicatable())
return false;
// It wouldn't make sense to rotate dealloc_stack without also rotating the
// alloc_stack, which is covered by isTriviallyDuplicatable.
else if (isa<DeallocStackInst>(inst))
return false;
else if (isa<FunctionRefInst>(inst)) {
moves.push_back(inst);
invariants.insert(inst);