1 // Copyright 2017-2019 VMware, Inc. 2 // SPDX-License-Identifier: BSD-2-Clause 3 // 4 // The BSD-2 license (the License) set forth below applies to all parts of the 5 // Cascade project. You may not use this file except in compliance with the 6 // License. 7 // 8 // BSD-2 License 9 // 10 // Redistribution and use in source and binary forms, with or without 11 // modification, are permitted provided that the following conditions are met: 12 // 13 // 1. Redistributions of source code must retain the above copyright notice, this 14 // list of conditions and the following disclaimer. 15 // 16 // 2. Redistributions in binary form must reproduce the above copyright notice, 17 // this list of conditions and the following disclaimer in the documentation 18 // and/or other materials provided with the distribution. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND 21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31 #ifndef CASCADE_SRC_VERILOG_TRANSFORM_DE_ALIAS_H 32 #define CASCADE_SRC_VERILOG_TRANSFORM_DE_ALIAS_H 33 34 #include <unordered_map> 35 #include <vector> 36 #include "verilog/ast/visitors/rewriter.h" 37 #include "verilog/ast/visitors/visitor.h" 38 39 namespace cascade { 40 41 class DeAlias : public Rewriter { 42 public: 43 DeAlias(); 44 ~DeAlias() override = default; 45 46 void run(ModuleDeclaration* md); 47 48 private: 49 class AliasTable : public Visitor { 50 public: 51 explicit AliasTable(const ModuleDeclaration* md); 52 ~AliasTable() override; 53 54 // Dealiases a variable or returns nullptr on failure. It is the 55 // responsibility of the caller to deallocate any resulting memory. 56 Identifier* dealias(const Identifier* id); 57 58 private: 59 struct Row { 60 const Identifier* target_; 61 std::vector<const Expression*> slices_; 62 bool done_; 63 }; 64 65 // Base case for populating the alias table. Record assignments of the 66 // form x = y, x = y[i], or x = y[i:j], where both sides of the 67 // assignment have identical bit-width. 68 void visit(const ContinuousAssign* ca) override; 69 // Inductive case for populating the alias table. Follow identifiers 70 // accumulate the slices that accumulate along the way. 71 void follow(Row& row); 72 // Final step for populating the alias table. Replaces slice chains 73 // with a single freshly constructed expression. 74 void collapse(Row& row); 75 // Returns the slice which is obtained by applying y after x. So 76 // merge([16:7], [6:4]) = x[7+6:7+4]. It is the responsibility of 77 // the caller to deallocate this memory. 78 Expression* merge(const Expression* x, const Expression* y); 79 80 // Alias Table: 81 std::unordered_map<const Identifier*, Row> aliases_; 82 }; 83 AliasTable* table_; 84 85 // Returns true if this is now an assignment of the form x = x. 86 bool is_self_assign(const ContinuousAssign* ca); 87 88 // Ignores attributes. 89 Attributes* rewrite(Attributes* as) override; 90 // Replaces an identifier with a de-aliased value. 91 Expression* rewrite(Identifier* id) override; 92 // Updates module items, ignores ports 93 ModuleDeclaration* rewrite(ModuleDeclaration* md) override; 94 // Does nothing. 95 Statement* rewrite(DebugStatement* ds) override; 96 }; 97 98 } // namespace cascade 99 100 #endif 101