SPV return from main: Simplify a legacy design such returns are not jumps to exit block.
Structured control-flow rules allow leaving the middle of a construct through a return, but not through a jump to a block that does a return. Addresses issue #58.
This commit is contained in:
@@ -65,8 +65,7 @@ Builder::Builder(unsigned int userNumber) :
|
||||
builderNumber(userNumber << 16 | SpvBuilderMagic),
|
||||
buildPoint(0),
|
||||
uniqueId(0),
|
||||
mainFunction(0),
|
||||
stageExit(0)
|
||||
mainFunction(0)
|
||||
{
|
||||
clearAccessChain();
|
||||
}
|
||||
@@ -723,19 +722,10 @@ Function* Builder::makeMain()
|
||||
std::vector<Id> params;
|
||||
|
||||
mainFunction = makeFunctionEntry(makeVoidType(), "main", params, &entry);
|
||||
stageExit = new Block(getUniqueId(), *mainFunction);
|
||||
|
||||
return mainFunction;
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
void Builder::closeMain()
|
||||
{
|
||||
setBuildPoint(stageExit);
|
||||
stageExit->addInstruction(new Instruction(NoResult, NoType, OpReturn));
|
||||
mainFunction->addBlock(stageExit);
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
Function* Builder::makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry)
|
||||
{
|
||||
@@ -756,14 +746,9 @@ Function* Builder::makeFunctionEntry(Id returnType, const char* name, std::vecto
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
void Builder::makeReturn(bool implicit, Id retVal, bool isMain)
|
||||
void Builder::makeReturn(bool implicit, Id retVal)
|
||||
{
|
||||
if (isMain && retVal)
|
||||
MissingFunctionality("return value from main()");
|
||||
|
||||
if (isMain)
|
||||
createBranch(stageExit);
|
||||
else if (retVal) {
|
||||
if (retVal) {
|
||||
Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
|
||||
inst->addIdOperand(retVal);
|
||||
buildPoint->addInstruction(inst);
|
||||
@@ -775,7 +760,7 @@ void Builder::makeReturn(bool implicit, Id retVal, bool isMain)
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
void Builder::leaveFunction(bool main)
|
||||
void Builder::leaveFunction()
|
||||
{
|
||||
Block* block = buildPoint;
|
||||
Function& function = buildPoint->getParent();
|
||||
@@ -791,10 +776,8 @@ void Builder::leaveFunction(bool main)
|
||||
// Given that this block is at the end of a function, it must be right after an
|
||||
// explicit return, just remove it.
|
||||
function.popBlock(block);
|
||||
} else if (main)
|
||||
makeMainReturn(true);
|
||||
else {
|
||||
// We're get a return instruction at the end of the current block,
|
||||
} else {
|
||||
// We'll add a return instruction at the end of the current block,
|
||||
// which for a non-void function is really error recovery (?), as the source
|
||||
// being translated should have had an explicit return, which would have been
|
||||
// followed by an unreachable block, which was handled above.
|
||||
@@ -805,9 +788,6 @@ void Builder::leaveFunction(bool main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (main)
|
||||
closeMain();
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
|
||||
Reference in New Issue
Block a user