|
| 1 | +/* |
| 2 | +Copyright 2016 VMware, Inc. |
| 3 | +
|
| 4 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +you may not use this file except in compliance with the License. |
| 6 | +You may obtain a copy of the License at |
| 7 | +
|
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | +Unless required by applicable law or agreed to in writing, software |
| 11 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +See the License for the specific language governing permissions and |
| 14 | +limitations under the License. |
| 15 | +*/ |
| 16 | + |
| 17 | +#include "syntacticEquivalence.h" |
| 18 | + |
| 19 | +namespace P4 { |
| 20 | + |
| 21 | +bool SameExpression::sameType(const IR::Type* left, const IR::Type* right) const { |
| 22 | + auto lt = typeMap->getType(left, true); |
| 23 | + auto rt = typeMap->getType(right, true); |
| 24 | + return TypeMap::equivalent(lt, rt); |
| 25 | +} |
| 26 | + |
| 27 | +bool SameExpression::sameExpressions(const IR::Vector<IR::Expression>* left, |
| 28 | + const IR::Vector<IR::Expression>* right) const { |
| 29 | + if (left->size() != right->size()) |
| 30 | + return false; |
| 31 | + for (unsigned i = 0; i < left->size(); i++) |
| 32 | + if (!sameExpression(left->at(i), right->at(i))) |
| 33 | + return false; |
| 34 | + return true; |
| 35 | +} |
| 36 | + |
| 37 | +bool SameExpression::sameExpression(const IR::Expression* left, const IR::Expression* right) const { |
| 38 | + CHECK_NULL(left); CHECK_NULL(right); |
| 39 | + if (left->node_type_name() != right->node_type_name()) |
| 40 | + return false; |
| 41 | + if (left->is<IR::Operation_Unary>()) { |
| 42 | + auto lu = left->to<IR::Operation_Unary>(); |
| 43 | + auto ru = right->to<IR::Operation_Unary>(); |
| 44 | + if (left->is<IR::Member>()) { |
| 45 | + auto lm = left->to<IR::Member>(); |
| 46 | + auto rm = right->to<IR::Member>(); |
| 47 | + if (lm->member != rm->member) |
| 48 | + return false; |
| 49 | + } else if (left->is<IR::Cast>()) { |
| 50 | + auto lc = left->to<IR::Cast>(); |
| 51 | + auto rc = right->to<IR::Cast>(); |
| 52 | + if (!sameType(lc->type, rc->type)) |
| 53 | + return false; |
| 54 | + } |
| 55 | + return sameExpression(lu->expr, ru->expr); |
| 56 | + } else if (left->is<IR::Operation_Binary>()) { |
| 57 | + auto lb = left->to<IR::Operation_Binary>(); |
| 58 | + auto rb = right->to<IR::Operation_Binary>(); |
| 59 | + return sameExpression(lb->left, rb->left) && sameExpression(lb->right, rb->right); |
| 60 | + } else if (left->is<IR::Operation_Ternary>()) { |
| 61 | + auto lt = left->to<IR::Operation_Ternary>(); |
| 62 | + auto rt = right->to<IR::Operation_Ternary>(); |
| 63 | + return sameExpression(lt->e0, rt->e0) && |
| 64 | + sameExpression(lt->e1, rt->e1) && |
| 65 | + sameExpression(lt->e2, rt->e2); |
| 66 | + } else if (left->is<IR::Constant>()) { |
| 67 | + return left->to<IR::Constant>()->value == right->to<IR::Constant>()->value; |
| 68 | + } else if (left->is<IR::Literal>()) { |
| 69 | + return *left == *right; |
| 70 | + } else if (left->is<IR::PathExpression>()) { |
| 71 | + auto ld = refMap->getDeclaration(left->to<IR::PathExpression>()->path, true); |
| 72 | + auto rd = refMap->getDeclaration(right->to<IR::PathExpression>()->path, true); |
| 73 | + return ld == rd; |
| 74 | + } else if (left->is<IR::TypeNameExpression>()) { |
| 75 | + auto ld = refMap->getDeclaration(left->to<IR::TypeNameExpression>()->typeName->path, true); |
| 76 | + auto rd = refMap->getDeclaration(right->to<IR::TypeNameExpression>()->typeName->path, true); |
| 77 | + return ld == rd; |
| 78 | + } else if (left->is<IR::ListExpression>()) { |
| 79 | + auto ll = left->to<IR::ListExpression>(); |
| 80 | + auto rl = right->to<IR::ListExpression>(); |
| 81 | + return sameExpressions(ll->components, rl->components); |
| 82 | + } else if (left->is<IR::MethodCallExpression>()) { |
| 83 | + auto lm = left->to<IR::MethodCallExpression>(); |
| 84 | + auto rm = right->to<IR::MethodCallExpression>(); |
| 85 | + if (!sameExpression(lm->method, rm->method)) |
| 86 | + return false; |
| 87 | + if (lm->typeArguments->size() != rm->typeArguments->size()) |
| 88 | + return false; |
| 89 | + for (unsigned i = 0; i < lm->typeArguments->size(); i++) |
| 90 | + if (!sameType(lm->typeArguments->at(i), rm->typeArguments->at(i))) |
| 91 | + return false; |
| 92 | + return sameExpressions(lm->arguments, rm->arguments); |
| 93 | + } else if (left->is<IR::ConstructorCallExpression>()) { |
| 94 | + auto lc = left->to<IR::ConstructorCallExpression>(); |
| 95 | + auto rc = right->to<IR::ConstructorCallExpression>(); |
| 96 | + if (!sameType(lc->constructedType, rc->constructedType)) |
| 97 | + return false; |
| 98 | + return sameExpressions(lc->arguments, rc->arguments); |
| 99 | + } else { |
| 100 | + BUG("%1%: Unexpected expression", left); |
| 101 | + } |
| 102 | +} |
| 103 | + |
| 104 | + |
| 105 | +} // namespace P4 |
0 commit comments