40 fFoundFunctionExit.push_back(
false);
41 fFoundBlockExit.push_back(
false);
44 bool visitExpressionPtr(std::unique_ptr<Expression>& expr)
override {
49 bool visitStatementPtr(std::unique_ptr<Statement>& stmt)
override {
50 if (fFoundFunctionExit.back() || fFoundBlockExit.back()) {
52 if (!stmt->is<
Nop>()) {
54 fUsage->remove(stmt.get());
60 switch (stmt->kind()) {
61 case Statement::Kind::kReturn:
64 fFoundFunctionExit.back() =
true;
67 case Statement::Kind::kBreak:
73 fFoundBlockExit.back() =
true;
76 case Statement::Kind::kExpression:
78 case Statement::Kind::kVarDeclaration:
82 case Statement::Kind::kBlock:
84 return INHERITED::visitStatementPtr(stmt);
86 case Statement::Kind::kDo: {
89 fFoundBlockExit.push_back(
false);
90 bool result = INHERITED::visitStatementPtr(stmt);
91 fFoundBlockExit.pop_back();
94 case Statement::Kind::kFor: {
97 fFoundFunctionExit.push_back(
false);
98 fFoundBlockExit.push_back(
false);
99 bool result = INHERITED::visitStatementPtr(stmt);
100 fFoundBlockExit.pop_back();
101 fFoundFunctionExit.pop_back();
104 case Statement::Kind::kIf: {
110 fFoundFunctionExit.push_back(
false);
111 fFoundBlockExit.push_back(
false);
113 bool foundFunctionExitOnTrue = fFoundFunctionExit.back();
114 bool foundLoopExitOnTrue = fFoundBlockExit.back();
115 fFoundFunctionExit.pop_back();
116 fFoundBlockExit.pop_back();
118 fFoundFunctionExit.push_back(
false);
119 fFoundBlockExit.push_back(
false);
121 bool foundFunctionExitOnFalse = fFoundFunctionExit.back();
122 bool foundLoopExitOnFalse = fFoundBlockExit.back();
123 fFoundFunctionExit.pop_back();
124 fFoundBlockExit.pop_back();
126 fFoundFunctionExit.back() |= foundFunctionExitOnTrue &&
127 foundFunctionExitOnFalse;
128 fFoundBlockExit.back() |= foundLoopExitOnTrue &&
129 foundLoopExitOnFalse;
132 case Statement::Kind::kSwitch: {
139 bool foundCaseWithoutReturn =
false;
140 bool hasDefault =
false;
141 for (std::unique_ptr<Statement>& c : sw.
cases()) {
148 fFoundFunctionExit.push_back(
false);
149 fFoundBlockExit.push_back(
false);
168 foundCaseWithoutReturn |= !fFoundFunctionExit.back();
173 foundCaseWithoutReturn |=
174 (!fFoundFunctionExit.back() && fFoundBlockExit.back());
177 fFoundFunctionExit.pop_back();
178 fFoundBlockExit.pop_back();
181 fFoundFunctionExit.back() |= !foundCaseWithoutReturn && hasDefault;
184 case Statement::Kind::kSwitchCase:
200 for (std::unique_ptr<ProgramElement>& pe : elements) {
202 UnreachableCodeEliminator visitor{
usage};
#define INHERITED(method,...)
SkSpan(Container &&) -> SkSpan< std::remove_pointer_t< decltype(std::data(std::declval< Container >()))> >
std::unique_ptr< Statement > & body()
std::unique_ptr< Statement > & ifTrue()
std::unique_ptr< Statement > & ifFalse()
static std::unique_ptr< Statement > Make()
std::unique_ptr< Statement > & statement()
static void eliminate_unreachable_code(SkSpan< std::unique_ptr< ProgramElement > > elements, ProgramUsage *usage)
static void usage(char *argv0)
std::vector< std::unique_ptr< ProgramElement > > fElements
std::vector< std::unique_ptr< ProgramElement > > fOwnedElements
std::unique_ptr< ProgramUsage > fUsage