mirror of
git://projects.qi-hardware.com/eda-tools.git
synced 2024-11-26 16:01:31 +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)
|
void field_finalize(struct field *field)
|
||||||
{
|
{
|
||||||
const struct selector *sel;
|
const struct selector *sel, *s2;
|
||||||
struct condition *cond;
|
struct condition *cond;
|
||||||
|
const struct condition *c2;
|
||||||
|
|
||||||
for (sel = field->sel; sel; sel = sel->next)
|
for (sel = field->sel; sel; sel = sel->next)
|
||||||
for (cond = sel->cond; cond; cond = cond->next)
|
for (cond = sel->cond; cond; cond = cond->next)
|
||||||
@ -88,6 +104,14 @@ void field_finalize(struct field *field)
|
|||||||
&cond->value))
|
&cond->value))
|
||||||
yyerrorf("invalid value in selection");
|
yyerrorf("invalid value in selection");
|
||||||
/* @@@ indicate exact location */
|
/* @@@ 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"
|
#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)
|
void dump_relop(FILE *file, enum relop op)
|
||||||
{
|
{
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
26
b2/relop.h
26
b2/relop.h
@ -16,15 +16,31 @@
|
|||||||
#include <stdio.h>
|
#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 {
|
enum relop {
|
||||||
rel_lt = 1 << 0,
|
rel_lt = 1 << idx_lt,
|
||||||
rel_le = 1 << 1,
|
rel_le = 1 << idx_le,
|
||||||
rel_eq = 1 << 2,
|
rel_eq = 1 << idx_eq,
|
||||||
rel_ge = 1 << 3,
|
rel_ge = 1 << idx_ge,
|
||||||
rel_gt = 1 << 4,
|
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);
|
void dump_relop(FILE *file, enum relop op);
|
||||||
|
|
||||||
#endif /* !RELOP_H */
|
#endif /* !RELOP_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user