Skip to content

Commit 6dc4dee

Browse files
committed
[Test] Improved inst/block offset subscripting.
1 parent 49405aa commit 6dc4dee

File tree

1 file changed

+55
-34
lines changed

1 file changed

+55
-34
lines changed

lib/SILOptimizer/UtilityPasses/ParseTestSpecification.cpp

Lines changed: 55 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/SILOptimizer/Utils/ParseTestSpecification.h"
1414
#include "swift/SIL/SILFunction.h"
1515
#include "swift/SIL/SILModule.h"
16+
#include "swift/SIL/SILSuccessor.h"
1617
#include "swift/SILOptimizer/Utils/InstructionDeleter.h"
1718
#include "llvm/ADT/DenseMap.h"
1819
#include "llvm/ADT/SmallVector.h"
@@ -84,55 +85,75 @@ SILInstruction *getInstruction(SILBasicBlock *block, unsigned long index) {
8485
llvm_unreachable("bad index!?");
8586
}
8687

88+
SILBasicBlock *getNextBlock(SILBasicBlock *block) {
89+
auto next = std::next(block->getIterator());
90+
if (next == block->getFunction()->end())
91+
return nullptr;
92+
return &*next;
93+
}
94+
95+
SILBasicBlock *getPreviousBlock(SILBasicBlock *block) {
96+
auto iterator = block->getIterator();
97+
if (iterator == block->getFunction()->begin())
98+
return nullptr;
99+
return &*std::prev(iterator);
100+
}
101+
102+
SILInstruction *getNextInstructionIgnoringBlocks(SILInstruction *instruction) {
103+
if (auto *nextInstruction = instruction->getNextInstruction())
104+
return nextInstruction;
105+
if (auto *nextBlock = getNextBlock(instruction->getParent()))
106+
return &nextBlock->front();
107+
return nullptr;
108+
}
109+
110+
SILInstruction *
111+
getPreviousInstructionIgnoringBlocks(SILInstruction *instruction) {
112+
if (auto *previousInstruction = instruction->getPreviousInstruction())
113+
return previousInstruction;
114+
if (auto *previousBlock = getPreviousBlock(instruction->getParent()))
115+
return &previousBlock->back();
116+
return nullptr;
117+
}
118+
87119
SILInstruction *getInstructionOffsetFrom(SILInstruction *base, long offset) {
88120
if (offset == 0) {
89121
return base;
90122
}
123+
auto *instruction = base;
91124
if (offset > 0) {
92-
Optional<unsigned long> baseIndex;
93-
unsigned long index = 0;
94-
for (auto &block : *base->getFunction()) {
95-
for (auto &other : block) {
96-
if (baseIndex && index == (*baseIndex + offset)) {
97-
return &other;
98-
}
99-
if (&other == base) {
100-
baseIndex = index;
101-
}
102-
++index;
103-
}
104-
}
105-
llvm_unreachable("positive offset outside of function!?");
106-
}
107-
SmallVector<SILInstruction *, 64> instructions;
108-
unsigned long index = 0;
109-
for (auto &block : *base->getFunction()) {
110-
for (auto &other : block) {
111-
instructions.push_back(&other);
112-
if (&other == base) {
113-
return instructions[index + offset];
114-
}
115-
++index;
125+
for (auto index = 0; index < offset; ++index) {
126+
instruction = getNextInstructionIgnoringBlocks(instruction);
127+
assert(instruction && "too large an offset!?");
116128
}
129+
return instruction;
117130
}
118-
llvm_unreachable("never found instruction in its own function!?");
131+
// offset < 0
132+
for (auto index = 0; index > offset; --index) {
133+
instruction = getPreviousInstructionIgnoringBlocks(instruction);
134+
assert(instruction && "too negative an offset!?");
135+
}
136+
return instruction;
119137
}
120138

121139
SILBasicBlock *getBlockOffsetFrom(SILBasicBlock *base, long offset) {
122140
if (offset == 0)
123141
return base;
124-
if (offset < 0) {
125-
auto iterator = base->getIterator();
126-
for (auto counter = 0; counter > offset; --counter) {
127-
iterator = std::prev(iterator);
142+
if (offset > 0) {
143+
auto *block = base;
144+
for (auto counter = 0; counter < offset; ++counter) {
145+
block = getNextBlock(block);
146+
assert(block && "too large an offset!?");
128147
}
129-
return &*iterator;
148+
return block;
130149
}
131-
auto iterator = base->getIterator();
132-
for (auto counter = 0; counter < offset; ++counter) {
133-
iterator = std::next(iterator);
150+
// offset < 0
151+
auto *block = base;
152+
for (auto counter = 0; counter > offset; --counter) {
153+
block = getPreviousBlock(block);
154+
assert(block && "too negative an offset!?");
134155
}
135-
return &*iterator;
156+
return block;
136157
}
137158

138159
SILBasicBlock *getBlock(SILFunction *function, unsigned long index) {

0 commit comments

Comments
 (0)