mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-22 21:32:29 +02:00
b2/: add test for redundant conditions in hierarchy
This commit is contained in:
parent
2239440ef1
commit
39382b1872
26
b2/chr.c
26
b2/chr.c
@ -77,10 +77,26 @@ struct condition *new_condition(enum relop relop, const char *word)
|
||||
}
|
||||
|
||||
|
||||
static int comp(const void *a, enum relop op, const void *b, const void *user)
|
||||
{
|
||||
return compare(user, a, op, b);
|
||||
}
|
||||
|
||||
|
||||
static void check_redundant(const struct field *f,
|
||||
const struct condition *c1, const struct condition *c2)
|
||||
{
|
||||
if (relop_implies(c1->relop, c2->relop, &c1->value, &c2->value,
|
||||
comp, f->fmt))
|
||||
yywarn("redundant condition");
|
||||
}
|
||||
|
||||
|
||||
void field_finalize(struct field *field)
|
||||
{
|
||||
const struct selector *sel;
|
||||
const struct selector *sel, *s2;
|
||||
struct condition *cond;
|
||||
const struct condition *c2;
|
||||
|
||||
for (sel = field->sel; sel; sel = sel->next)
|
||||
for (cond = sel->cond; cond; cond = cond->next)
|
||||
@ -88,6 +104,14 @@ void field_finalize(struct field *field)
|
||||
&cond->value))
|
||||
yyerrorf("invalid value in selection");
|
||||
/* @@@ indicate exact location */
|
||||
for (sel = field->sel; sel; sel = sel->next)
|
||||
for (cond = sel->cond; cond; cond = cond->next) {
|
||||
for (c2 = cond->next; c2; c2 = c2->next)
|
||||
check_redundant(field, cond, c2);
|
||||
for (s2 = sel->next; s2; s2 = s2->next)
|
||||
for (c2 = s2->cond; c2; c2 = c2->next)
|
||||
check_redundant(field, cond, c2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
72
b2/relop.c
72
b2/relop.c
@ -16,6 +16,78 @@
|
||||
#include "relop.h"
|
||||
|
||||
|
||||
/*
|
||||
* Operator to use for
|
||||
*
|
||||
* forall X: (A op B) == ((X opa A) -> (X opb B))
|
||||
*
|
||||
* For unlimited sets of values:
|
||||
*
|
||||
* opa -> < <= == >= >
|
||||
* opb
|
||||
* < >= >= 0 0 0
|
||||
* <= > >= 0 0 0
|
||||
* == > >= == <= <
|
||||
* >= 0 0 0 <= <
|
||||
* > 0 0 0 <= <=
|
||||
*
|
||||
* For limited sets of values, we could decide also in some edge cases,
|
||||
* but let's save such sophistication for later.
|
||||
*/
|
||||
|
||||
|
||||
static const enum relop implies_op[idx_n][idx_n] = {
|
||||
[idx_lt][idx_lt] = rel_ge,
|
||||
[idx_lt][idx_le] = rel_ge,
|
||||
|
||||
[idx_le][idx_lt] = rel_gt,
|
||||
[idx_le][idx_le] = rel_ge,
|
||||
|
||||
[idx_eq][idx_lt] = rel_gt,
|
||||
[idx_eq][idx_le] = rel_ge,
|
||||
[idx_eq][idx_eq] = rel_eq,
|
||||
};
|
||||
|
||||
|
||||
static int relop2index(enum relop op)
|
||||
{
|
||||
switch (op) {
|
||||
case rel_lt:
|
||||
return idx_lt;
|
||||
case rel_le:
|
||||
return idx_le;
|
||||
case rel_eq:
|
||||
return idx_eq;
|
||||
case rel_ge:
|
||||
return idx_ge;
|
||||
case rel_gt:
|
||||
return idx_gt;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum relop swap_op(enum relop op)
|
||||
{
|
||||
return idx_n-1-relop2index(op);
|
||||
}
|
||||
|
||||
|
||||
int relop_implies(enum relop opa, enum relop opb, const void *a, const void *b,
|
||||
int (*cmp)(const void *a, enum relop op, const void *b, const void *user),
|
||||
const void *user)
|
||||
{
|
||||
if (opa <= opb)
|
||||
return cmp(a,
|
||||
implies_op[relop2index(opa)][relop2index(opb)], b, user);
|
||||
else
|
||||
return cmp(b,
|
||||
swap_op(implies_op[relop2index(opb)][relop2index(opa)]),
|
||||
a, user);
|
||||
}
|
||||
|
||||
|
||||
void dump_relop(FILE *file, enum relop op)
|
||||
{
|
||||
switch (op) {
|
||||
|
26
b2/relop.h
26
b2/relop.h
@ -16,15 +16,31 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
enum relop_idx {
|
||||
idx_lt = 0,
|
||||
idx_le = 1,
|
||||
idx_eq = 2,
|
||||
idx_ge = 3,
|
||||
idx_gt = 4,
|
||||
idx_n = 5
|
||||
};
|
||||
|
||||
enum relop {
|
||||
rel_lt = 1 << 0,
|
||||
rel_le = 1 << 1,
|
||||
rel_eq = 1 << 2,
|
||||
rel_ge = 1 << 3,
|
||||
rel_gt = 1 << 4,
|
||||
rel_lt = 1 << idx_lt,
|
||||
rel_le = 1 << idx_le,
|
||||
rel_eq = 1 << idx_eq,
|
||||
rel_ge = 1 << idx_ge,
|
||||
rel_gt = 1 << idx_gt,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* relop_implies checks whether, for all X: (X opb A) -> (X opa B)
|
||||
*/
|
||||
|
||||
int relop_implies(enum relop opa, enum relop opb, const void *a, const void *b,
|
||||
int (*cmp)(const void *a, enum relop op, const void *b, const void *user),
|
||||
const void *user);
|
||||
void dump_relop(FILE *file, enum relop op);
|
||||
|
||||
#endif /* !RELOP_H */
|
||||
|
Loading…
Reference in New Issue
Block a user