MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / SplitLoopHeader

Method SplitLoopHeader

source/opt/cfg.cpp:192–360  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

190}
191
192BasicBlock* CFG::SplitLoopHeader(BasicBlock* bb) {
193 assert(bb->GetLoopMergeInst() && "Expecting bb to be the header of a loop.");
194
195 Function* fn = bb->GetParent();
196 IRContext* context = module_->context();
197
198 // Get the new header id up front. If we are out of ids, then we cannot split
199 // the loop.
200 uint32_t new_header_id = context->TakeNextId();
201 if (new_header_id == 0) {
202 return nullptr;
203 }
204
205 // Find the insertion point for the new bb.
206 Function::iterator header_it = std::find_if(
207 fn->begin(), fn->end(),
208 [bb](BasicBlock& block_in_func) { return &block_in_func == bb; });
209 assert(header_it != fn->end());
210
211 const std::vector<uint32_t>& pred = preds(bb->id());
212 // Find the back edge
213 BasicBlock* latch_block = nullptr;
214 Function::iterator latch_block_iter = header_it;
215 for (; latch_block_iter != fn->end(); ++latch_block_iter) {
216 // If blocks are in the proper order, then the only branch that appears
217 // after the header is the latch.
218 if (std::find(pred.begin(), pred.end(), latch_block_iter->id()) !=
219 pred.end()) {
220 break;
221 }
222 }
223 assert(latch_block_iter != fn->end() && "Could not find the latch.");
224 latch_block = &*latch_block_iter;
225
226 RemoveSuccessorEdges(bb);
227
228 // Create the new header bb basic bb.
229 // Leave the phi instructions behind.
230 auto iter = bb->begin();
231 while (iter->opcode() == spv::Op::OpPhi) {
232 ++iter;
233 }
234
235 BasicBlock* new_header = bb->SplitBasicBlock(context, new_header_id, iter);
236 context->AnalyzeDefUse(new_header->GetLabelInst());
237
238 // Update cfg
239 RegisterBlock(new_header);
240
241 // Update bb mappings.
242 context->set_instr_block(new_header->GetLabelInst(), new_header);
243 new_header->ForEachInst([new_header, context](Instruction* inst) {
244 context->set_instr_block(inst, new_header);
245 });
246
247 // If |bb| was the latch block, the branch back to the header is not in
248 // |new_header|.
249 if (latch_block == bb) {

Callers 4

BranchToBlockMethod · 0.80
BreakFromConstructMethod · 0.80
TEST_FFunction · 0.80

Calls 15

findFunction · 0.85
GetLoopMergeInstMethod · 0.80
SplitBasicBlockMethod · 0.80
GetLabelInstMethod · 0.80
set_instr_blockMethod · 0.80
ContinueBlockIdMethod · 0.80
SetInOperandMethod · 0.80
WhileEachPhiInstMethod · 0.80
NumInOperandsMethod · 0.80
AddPhiMethod · 0.80
RemoveFromListMethod · 0.80

Tested by 1

TEST_FFunction · 0.64