Skip to content
Open
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
8 changes: 8 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,11 @@
like before.
- `release 7 7134`
- `release 6 6449`
- `note 6` DMLC no longer emits warnings saying
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will no longer emit the subset of WEXPERIMENTAL warnings saying...

maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose not to because I didn't want to bore the reader with details, but it does make sense to mention WEXPERIMENTAL because of how --no-warn=WEXPERIMENTAL is sprinkled in makefiles.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah that's mostly why I figured it was a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still not mention of WEXPERIMENTAL, here. I still think you should do so, but whichever way you go about it is up to you.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Toplevel if logic is 1.4 exclusive, and thus so should this releasenote.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree. You are right that they are exclusive for 1.4 files, but their only use is in the context of 1.2 devices: The only allowed identifier is dml_1_2, so the construct is only relevant for common code intended for use in 1.2.

Copy link
Contributor

@lwaern-intel lwaern-intel Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the construct is only relevant for common code intended for use in 1.2.

Only for the time being. I think we've both agreed upon extending the conditional to also allow the use of the compat params?

Nevertheless, I guess this is a matter of perspective of where a releasenote belongs. I was thinking "1.4, because this feature is only available in 1.4 files", while you're arguing the use of it is only significant due to how it impact 1.2 devices. Because of that, I'm fine with it being in RELEASENOTES.dml; but I would note that your argument sounds like it'd belong in RELEASENOTES-1.2.md, which I would heavily disagree with.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The releasenote split between 1.2/1.4/both is inherently fuzzy and somewhat questionable. What matters the most is that the end-user sees a note attached to the right package version, this happens no matter what releasenote file we pick; the choice of file is not so important.

I guess the advantage of the split is that many syntax additions are 1.4 specific, and putting it in -1.4 eliminates the need to mention this in text.

I think it would make sense at least to merge RELEASENOTES and RELEASENOTES-1.2. A total 7 notes were 1.2 specific over the past 3 years.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what action are we taking?

`top-level '#if' body with unsupported statements`. These warnings were
often triggered in common code, causing excessive polution in build logs unless `--no-warn=WEXPERIMENTAL` was passed to DMLC.
The same rules as before apply to `#if` statements: Statements such as
`param` and `template` are forbidden inside `#if`, but a special exception
allows forbidden statements to appear specifically inside an `#if (dml_1_2)`
block. The warning message was meant to highlight this irregularity, but
caused more harm than good; error messages surrounding the special case have been improved instead.
32 changes: 28 additions & 4 deletions doc/1.4/language.md
Original file line number Diff line number Diff line change
Expand Up @@ -2488,8 +2488,8 @@ The *object declarations* are any number of declarations of objects, session
variables, saved variables, methods, `in each` statements, or other `#if`
statements, but not parameters or `is` statements. When the conditional is
`true` (or if it's the else branch of a false conditional), the object
declarations are treated as if they had appeared without any surrounding *#if*.
So the two following declarations are equivalent:
declarations are treated as if they had appeared without any surrounding `#if`.
Thus, the two following snippets are equivalent:

```
#if (true) {
Expand All @@ -2499,12 +2499,36 @@ So the two following declarations are equivalent:
}
```

is equivalent to

```
register R size 4;
```

As a special exception, an `#if` statement that appears on top level is allowed
to contain any type of statement, as long as the condition doesn't reference
any identifiers other than `dml_1_2`, `true` and `false`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you do add dml_1_4 you'll need to update this accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for "only 1.2" is that I want to encourage users to consistently use the dml_1_2 form, for two reasons (or both are really the same reason):

  • Currently dml_1_2 is equivalent to !dml_1_4, but in a world where 1.2/1.4/1.6 coexist they are not, and in this case dml_1_2 better expresses what you mean: you want stuff to change when you switch between "old" and "new". Comparing for equality to 1.2 is future proof because we will never add new old versions.
  • Saying 1.2 in code is a clear marker that the #if is a legacy thing that can safely be removed once the codebase is free from DML 1.2 code. If we say 1.4, then this is less obvious.

For this reason, I don't yet see a real use case where dml_1_4 is preferable over dml_1_2, so I don't see a compelling reason to spend time here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MMmmfmffhghh... fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, no -- not fine. I don't understand why your favored approach is to use the restrictions placed on top-level #ifs as a vehicle against dml_1_4. If you dislike dml_1_4 so much and want to discourage its use -- why does it exist at all in the first place? I'd prefer we remove dml_1_4 entirely rather than having this strange inconsistency.

This is often useful while migrating the devices of a system from DML 1.2
to DML 1.4, as it allows conditional definitions of templates in common
code used from both DML 1.2 and DML 1.4.
For example, let's say an existing template `reset_to_seven`
is used in DML 1.2 code to set the reset value of a field to 7 in DML 1.2.
The parameters that control reset values have changed from DML 1.2 to DML 1.4,
and one way to handle this is to provide separate template definitions
depending on whether the device uses DML 1.2 or DML 1.4:
```
#if (dml_1_2) {
template seven is field {
param hard_reset_value = 7;
param soft_reset_value = 7;
}
} #else {
template seven is field {
param init_val = 7;
}
}
```
Later, when all related devices have been ported to DML 1.4,
the `dml_1_2` clause can be removed.

## In Each Declarations

In Each declarations are a convenient mechanism to apply a
Expand Down
17 changes: 7 additions & 10 deletions py/dml/dmlparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,12 +272,12 @@ def toplevel_param(t):
def toplevel_if(t):
'''toplevel_if : hashif LPAREN expression RPAREN \
LBRACE device_statements RBRACE toplevel_else'''
if all(stmt.kind in allowed_in_hashif for stmt in t[6] + t[8]):
t[0] = ast.hashif(site(t), t[3], t[6], t[8])
bad_stmts = [stmt for stmt in t[6] + t[8]
if stmt.kind not in allowed_in_hashif]
if bad_stmts:
t[0] = ast.toplevel_if(site(t), t[3], t[6], t[8], bad_stmts)
else:
report(WEXPERIMENTAL(site(t), ("top-level 'if' body with unsupported "
+ "statements")))
t[0] = ast.toplevel_if(site(t), t[3], t[6], t[8])
t[0] = ast.hashif(site(t), t[3], t[6], t[8])

@prod_dml14
def toplevel_else_no(t):
Expand Down Expand Up @@ -1023,12 +1023,9 @@ def validate_if_body(stmts):
for stmt in stmts:
if stmt.kind in allowed_in_hashif:
result.append(stmt)
elif stmt.kind == 'param':
report(ECONDP(stmt.site))
elif stmt.kind == 'is':
report(ECONDT(stmt.site))
else:
raise ICE(stmt.site, 'unknown kind %r' % (stmt.kind,))
assert stmt.kind in {'param', 'is'}
report(EBADCONDSTMT(stmt.site, stmt.kind))
return result

@prod_dml12
Expand Down
18 changes: 8 additions & 10 deletions py/dml/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -810,19 +810,17 @@ class EUNINITIALIZED(DMLError):
"""
fmt = "value of parameter %s is not yet initialized"

class ECONDP(DMLError):
class EBADCONDSTMT(DMLError):
"""
It is not permitted to declare a parameter directly inside an
`if` conditional.
"""
fmt = "conditional parameters are not allowed"
`#if` statements in object scope are only allowed to contain
certain kinds of declarations: objects, `method`, `session`,
`saved`, `#if`, `in each`, or `error`.

class ECONDT(DMLError):
"""
It is not permitted to use a template directly inside an
`if` conditional.
A special exception is that a `#if` on top scope may contain any
kind of statement as long as the `#if` condition doesn't reference
any identifiers other than `dml_1_2`, `true`, and `false`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget dml_1_4!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait. actually you can't reference dml_1_4. what? Did I trick myself into believing that? That's pretty bad since I've communicated that you're able to reference dml_1_4 to everyone I've explained experimental #if to...

That feels like a bad inconsistency. I mean, I got confused about it. Maybe you should add dml_1_4 to be able to be referenced. I ask that totally not at all out of a self-interested need to retroactively make my improper communication proper, I promise

"""
fmt = "conditional templates are not allowed"
fmt = "'%s' declaration not allowed inside `#if`"
Copy link
Contributor

@lwaern-intel lwaern-intel Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth highlighting both in error documentation, and, in fact, the error message itself, that the forbidden declaration is only forbidden directly within #if, because that fact is a very big deal and may sometimes help people immediately figure out how to work around the issue.

The impact is also rather small (at least for the error message):

fmt = "'%s' declaration not allowed immediately inside `#if`"
`#if` statements in object scope are only allowed to contain
certain kinds of declarations: objects, `method`, `session`,
`saved`, `#if`, `in each`, or `error`.
This does not apply recursively; object or `in each` blocks made
inside an `#if` are allowed to contain other kinds of declarations.


# TODO: Consider re-wording the semantics of this error, allocate_type is only
# relevant in 1.4 when imported from 1.2, and as per SIMICS-9393 this
Expand Down
18 changes: 11 additions & 7 deletions py/dml/toplevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,25 +148,29 @@ def scan_statements(filename, site, stmts):
[text] = s.args
footers.append(ctree.mkCText(s.site, text))
elif s.kind == 'toplevel_if':
[cond, tbranch, fbranch] = s.args
[cond, tbranch, fbranch, bad_stmts] = s.args
scope = symtab.Symtab()
bsite = SimpleSite('<builtin>',
dml_version=dml.globals.dml_version)
# HACK Add constants to scope typically defined by dml-builtins,
# which is not accessible here
def add_constant(name, expr):
constants = {
'dml_1_2': ctree.BoolConstant(
bsite, dml.globals.dml_version == (1, 2)),
'true': ctree.BoolConstant(bsite, True),
'false': ctree.BoolConstant(bsite, False),
}
for (name, expr) in constants.items():
scope.add(ctree.ExpressionSymbol(name, expr, bsite))

add_constant(
'dml_1_2',
ctree.BoolConstant(bsite, dml.globals.dml_version == (1, 2)))
add_constant('true', ctree.BoolConstant(bsite, True))
add_constant('false', ctree.BoolConstant(bsite, False))
try:
expr = ctree.as_bool(codegen.codegen_expression(
cond, None, scope))
if not expr.constant:
raise ENCONST(expr.site, expr)
except EIDENT:
for stmt in bad_stmts:
report(EBADCONDSTMT(stmt.site, stmt.kind))
except DMLError as e:
report(e)
else:
Expand Down
12 changes: 0 additions & 12 deletions test/1.2/errors/T_ECONDP.dml

This file was deleted.

19 changes: 0 additions & 19 deletions test/1.2/errors/T_ECONDT.dml

This file was deleted.

2 changes: 1 addition & 1 deletion test/1.2/misc/T_import_dml14.dml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ constant x = 0;

parameter is_dml_12 = true;

/// WARNING WEXPERIMENTAL dml14.dml
/// WARNING WEXPERIMENTAL dml12-compatibility.dml
/// SCAN-FOR-TAGS dml14.dml
import "dml14.dml";

Expand Down
3 changes: 0 additions & 3 deletions test/1.2/misc/dml14.dml
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ bank testbank is (miss_pattern_bank, function_mapped_bank) {

bank overridden_bank is (unified_hard_reset, unified_soft_reset);

/// WARNING WEXPERIMENTAL
#if (dml_1_2) {
import "io-memory.dml";
} #else {
Expand Down Expand Up @@ -515,10 +514,8 @@ attribute woa is (write_only_attr) {

param global_sym = 14;

/// WARNING WEXPERIMENTAL
#if (!dml_1_2) {
param cond = false;
/// WARNING WEXPERIMENTAL
} #else #if (!dml_1_2) {
error;
} #else {
Expand Down
52 changes: 52 additions & 0 deletions test/1.4/errors/T_EBADCONDSTMT.dml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
© 2024 Intel Corporation
SPDX-License-Identifier: MPL-2.0
*/
dml 1.4;

device test;

template empty {}

param yes = true;
#if (yes) {
/// ERROR EBADCONDSTMT
param p = 3;
/// ERROR EBADCONDSTMT
typedef int i_t;
} #else {
/// ERROR EBADCONDSTMT
template t {
}

/// ERROR EBADCONDSTMT
extern typedef int i_t;

/// ERROR EBADCONDSTMT
is empty;
}

#if (true) {
// no error
param p = 3;
extern typedef int i2_t;
}
#if (false) {
// no error
is empty;
param p = 3;
}
#if (dml_1_2) {
// no error
is empty;
param p = 3;
}

group g {
#if (true) {
/// ERROR EBADCONDSTMT
param p = 5;
// ERROR EBADCONDSTMT
is empty;
}
}
51 changes: 51 additions & 0 deletions test/1.4/structure/T_top_hashif.dml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
© 2024 Intel Corporation
SPDX-License-Identifier: MPL-2.0
*/
dml 1.4;

device test;

/// COMPILE-ONLY

#if (true) {
extern typedef int a_t;
typedef int b_t;
param p = 1;
} #else {
extern void *x;
import "nonexisting.dml";
param p = 2;
error;
}

#if (p != 1) { error; }

#if (false) {
typedef void *a_t;
extern typedef void *b_t;
error;
template t { error; }
} #else {
extern int x;
import "imported.dml";
template t { param from_t = true; }
}

#if (!imported) { error; }

is t;
#if (!from_t) { error; }

#if (dml_1_2 || false) {
error;
} #else {
#if (true) {
#if (!false) {
// nested top-level #ifs are permitted
param foo = true;
}
}
}

#if (!foo) { error; }
7 changes: 7 additions & 0 deletions test/1.4/structure/imported.dml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
© 2024 Intel Corporation
SPDX-License-Identifier: MPL-2.0
*/
dml 1.4;

param imported = true;