Add functions to find the matching ELSE, ENDIF expressions

ExpressionId FindMatchingEndif(ExpressionId id)
   - Finds the closing ENDIF expression for a given IF expression.

ExpressionId FindMatchingElse(ExpressionId id)
   - Finds the ELSE expression for a given IF expression.
   - Returns -1, if this IF doesn't have an else

This patch is a preparation to the code analyzing required
for various optimization passes.

Change-Id: I893102a757c6a0bcacbcc1190c2b8ef08314eb97
This commit is contained in:
Darius Rueckert
2019-12-20 15:55:54 +01:00
parent 678c05b289
commit fdf9cfd320
3 changed files with 156 additions and 1 deletions
@@ -31,9 +31,9 @@
// This file tests the ExpressionGraph class. This test depends on the
// correctness of Expression.
//
#include "ceres/codegen/internal/expression.h"
#include "ceres/codegen/internal/expression_graph.h"
#include "ceres/codegen/internal/expression.h"
#include "gtest/gtest.h"
namespace ceres {
@@ -146,6 +146,78 @@ TEST(ExpressionGraph, DependsOn) {
ASSERT_TRUE(graph.DependsOn(3, 1));
}
TEST(ExpressionGraph, FindMatchingEndif) {
ExpressionGraph graph;
graph.InsertBack(Expression::CreateCompileTimeConstant(1));
graph.InsertBack(Expression::CreateCompileTimeConstant(2));
graph.InsertBack(Expression::CreateBinaryCompare("<", 0, 1));
graph.InsertBack(Expression::CreateIf(2));
graph.InsertBack(Expression::CreateIf(2));
graph.InsertBack(Expression::CreateElse());
graph.InsertBack(Expression::CreateEndIf());
graph.InsertBack(Expression::CreateElse());
graph.InsertBack(Expression::CreateIf(2));
graph.InsertBack(Expression::CreateEndIf());
graph.InsertBack(Expression::CreateEndIf());
graph.InsertBack(Expression::CreateIf(2)); // < if without matching endif
EXPECT_EQ(graph.Size(), 12);
// Code <id>
// v_0 = 1 0
// v_1 = 2 1
// v_2 = v_0 < v_1 2
// IF (v_2) 3
// IF (v_2) 4
// ELSE 5
// ENDIF 6
// ELSE 7
// IF (v_2) 8
// ENDIF 9
// ENDIF 10
// IF(v_2) 11
EXPECT_EQ(graph.FindMatchingEndif(3), 10);
EXPECT_EQ(graph.FindMatchingEndif(4), 6);
EXPECT_EQ(graph.FindMatchingEndif(8), 9);
EXPECT_EQ(graph.FindMatchingEndif(11), kInvalidExpressionId);
}
TEST(ExpressionGraph, FindMatchingElse) {
ExpressionGraph graph;
graph.InsertBack(Expression::CreateCompileTimeConstant(1));
graph.InsertBack(Expression::CreateCompileTimeConstant(2));
graph.InsertBack(Expression::CreateBinaryCompare("<", 0, 1));
graph.InsertBack(Expression::CreateIf(2));
graph.InsertBack(Expression::CreateIf(2));
graph.InsertBack(Expression::CreateElse());
graph.InsertBack(Expression::CreateEndIf());
graph.InsertBack(Expression::CreateElse());
graph.InsertBack(Expression::CreateIf(2));
graph.InsertBack(Expression::CreateEndIf());
graph.InsertBack(Expression::CreateEndIf());
graph.InsertBack(Expression::CreateIf(2)); // < if without matching endif
EXPECT_EQ(graph.Size(), 12);
// Code <id>
// v_0 = 1 0
// v_1 = 2 1
// v_2 = v_0 < v_1 2
// IF (v_2) 3
// IF (v_2) 4
// ELSE 5
// ENDIF 6
// ELSE 7
// IF (v_2) 8
// ENDIF 9
// ENDIF 10
// IF(v_2) 11
EXPECT_EQ(graph.FindMatchingElse(3), 7);
EXPECT_EQ(graph.FindMatchingElse(4), 5);
EXPECT_EQ(graph.FindMatchingElse(8), kInvalidExpressionId);
EXPECT_EQ(graph.FindMatchingEndif(11), kInvalidExpressionId);
}
TEST(ExpressionGraph, InsertExpression_UpdateReferences) {
// This test checks if references to shifted expressions are updated
// accordingly.