summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-10-09 00:09:54 -0400
committerIlia Mirkin <[email protected]>2016-10-10 10:45:06 -0400
commitec05331a7b0d6b6bb84fa6452fbba4bf5dc25f83 (patch)
tree87984a405226681aa124ed790424a72c30d699aa
parent1f951216266a5f3d824d8b8da4a0cd4328d22d95 (diff)
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 <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index 7dff08a5ccc..db03281a4d4 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -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);