nv50/ir: only stick one preret per function

A function with multiple returns would have had multiple preret settings
at the top of the function. While this is unlikely to have caused issues
since we don't use functions in earnest, it could have in some cases
overflowed the call stack, in case a function had a lot of early
returns.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
This commit is contained in:
Ilia Mirkin
2016-10-09 00:09:54 -04:00
parent 1f95121626
commit ec05331a7b

View File

@@ -3465,10 +3465,13 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
if (!isEndOfSubroutine(ip + 1)) {
// insert a PRERET at the entry if this is an early return
// (only needed for sharing code in the epilogue)
BasicBlock *pos = getBB();
setPosition(BasicBlock::get(func->cfg.getRoot()), false);
mkFlow(OP_PRERET, leave, CC_ALWAYS, NULL)->fixed = 1;
setPosition(pos, true);
BasicBlock *root = BasicBlock::get(func->cfg.getRoot());
if (root->getEntry() == NULL || root->getEntry()->op != OP_PRERET) {
BasicBlock *pos = getBB();
setPosition(root, false);
mkFlow(OP_PRERET, leave, CC_ALWAYS, NULL)->fixed = 1;
setPosition(pos, true);
}
}
mkFlow(OP_RET, NULL, CC_ALWAYS, NULL)->fixed = 1;
bb->cfg.attach(&leave->cfg, Graph::Edge::CROSS);