Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not all Type_InfInt are the same - keep track of ones that need to be unified #3828

Merged
merged 1 commit into from
Jan 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ class ConstantTypeSubstitution : public Transform {
auto cstType = typeMap->getType(getOriginal(), true);
if (!cstType->is<IR::ITypeVar>()) return cst;
auto repl = cstType;
while (repl != nullptr && repl->is<IR::ITypeVar>())
repl = subst->get(repl->to<IR::ITypeVar>());
if (repl != nullptr && !repl->is<IR::ITypeVar>()) {
// maybe the substitution could not infer a width...
while (repl->is<IR::ITypeVar>()) {
auto next = subst->get(repl->to<IR::ITypeVar>());
if (!next) break;
repl = next;
}
if (repl != cstType) {
// We may replace a type variable with another one
LOG2("Inferred type " << repl << " for " << cst);
cst = new IR::Constant(cst->srcInfo, repl, cst->value, cst->base);
} else {
Expand Down Expand Up @@ -2118,7 +2121,7 @@ const IR::Node* TypeInference::postorder(IR::P4ListExpression* expression) {
ConstantTypeSubstitution cts(tvs, refMap, typeMap, this);
auto converted = cts.convert(c);
vec->push_back(converted);
changed = true;
changed = changed || converted != c;
} else {
vec->push_back(c);
}
Expand Down
2 changes: 1 addition & 1 deletion frontends/p4/typeChecking/typeConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ TypeVariableSubstitution* TypeConstraints::solve() {
if (!success) return nullptr;
}
LOG3("Constraint solution:\n" << currentSubstitution);
return currentSubstitution->trim();
return currentSubstitution;
}

bool TypeConstraints::isUnifiableTypeVariable(const IR::Type* type) {
Expand Down
9 changes: 0 additions & 9 deletions frontends/p4/typeChecking/typeSubstitution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,6 @@ bool TypeVariableSubstitution::setBindings(const IR::Node* errorLocation,
return true;
}

TypeVariableSubstitution* TypeVariableSubstitution::trim() const {
TypeVariableSubstitution* result = new TypeVariableSubstitution();
for (auto it : binding) {
if (it.first->is<IR::Type_InfInt>() && it.second->is<IR::Type_InfInt>()) continue;
result->setBinding(it.first, it.second);
}
return result;
}

// to call from gdb
void dump(P4::TypeVariableSubstitution& tvs) { std::cout << tvs << std::endl; }
void dump(P4::TypeVariableSubstitution* tvs) { std::cout << *tvs << std::endl; }
Expand Down
4 changes: 1 addition & 3 deletions frontends/p4/typeChecking/typeSubstitution.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,13 @@ class TypeVariableSubstitution final : public TypeSubstitution<const IR::ITypeVa
TypeVariableSubstitution(const TypeVariableSubstitution& other) = default;
bool setBindings(const IR::Node* errorLocation, const IR::TypeParameters* params,
const IR::Vector<IR::Type>* args);
/// Returns an empyty string on error, or an error message format otherwise.
/// Returns an empty string on error, or an error message format otherwise.
/// The error message should be used with 'var' and 'substitution' as arguments when
/// reporting an error (i.e., it may contain %1% and %2% inside).
cstring compose(const IR::ITypeVar* var, const IR::Type* substitution);
// In this variant of compose all variables in 'other' that are
// assigned to are disjoint from all variables already in 'this'.
void simpleCompose(const TypeVariableSubstitution* other);
// Remove substitutions of the form int->int.
TypeVariableSubstitution* trim() const;
};

} // namespace P4
Expand Down
12 changes: 12 additions & 0 deletions testdata/p4_16_samples/issue3806.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
header ethernet_t {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> eth_type;
}
struct Headers {
ethernet_t eth_hdr;
}

void f (inout Headers h) {
h.eth_hdr = h.eth_hdr.eth_type == 1 ? {1, 1, 1} : {2, 2, 2};
}
13 changes: 13 additions & 0 deletions testdata/p4_16_samples_outputs/issue3806-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
header ethernet_t {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> eth_type;
}

struct Headers {
ethernet_t eth_hdr;
}

void f(inout Headers h) {
h.eth_hdr = (h.eth_hdr.eth_type == 16w1 ? (ethernet_t){dst_addr = 48w1,src_addr = 48w1,eth_type = 16w1} : (ethernet_t){dst_addr = 48w2,src_addr = 48w2,eth_type = 16w2});
}
10 changes: 10 additions & 0 deletions testdata/p4_16_samples_outputs/issue3806-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
header ethernet_t {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> eth_type;
}

struct Headers {
ethernet_t eth_hdr;
}

13 changes: 13 additions & 0 deletions testdata/p4_16_samples_outputs/issue3806.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
header ethernet_t {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> eth_type;
}

struct Headers {
ethernet_t eth_hdr;
}

void f(inout Headers h) {
h.eth_hdr = (h.eth_hdr.eth_type == 1 ? { 1, 1, 1 } : { 2, 2, 2 });
}
1 change: 1 addition & 0 deletions testdata/p4_16_samples_outputs/issue3806.p4-stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[--Wwarn=missing] warning: Program does not contain a `main' module