Skip to content

Commit

Permalink
Corrections and optimizations for nordshift
Browse files Browse the repository at this point in the history
* Corrects corner cases
* Handles variable slices on the form dst[i*stride +: width] = src
  • Loading branch information
daglem committed Aug 8, 2023
1 parent 5574fa8 commit 52b8b88
Showing 1 changed file with 32 additions and 11 deletions.
43 changes: 32 additions & 11 deletions frontends/ast/simplify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2389,18 +2389,29 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin
int stride = 1;
int div_stride = 1;

// Optimization: Remove multiplication of index by stride for two-dimensional packed arrays and
// variable slices on the form dst = src[i*w +: w].
if (!source_offset && shift_expr->type == AST_MUL &&
((shift_expr->children[0]->type == AST_CONSTANT && (int)shift_expr->children[0]->integer == result_width) ||
(shift_expr->children[1]->type == AST_CONSTANT && (int)shift_expr->children[1]->integer == result_width)))
// Extract (index)*(width) from non_opt_range pattern (@selfsz@((index)*(width)))+(0)).
AstNode *lsb_expr =
shift_expr->type == AST_ADD && shift_expr->children[0]->type == AST_SELFSZ &&
shift_expr->children[1]->type == AST_CONSTANT && shift_expr->children[1]->integer == 0 ?
shift_expr->children[0]->children[0] :
shift_expr;

// Optimization: Extract stride from indexing of two-dimensional packed arrays and
// variable slices on the form dst = src[i*stride +: width].
if (!source_offset && lsb_expr->type == AST_MUL &&
(lsb_expr->children[0]->type == AST_CONSTANT || lsb_expr->children[1]->type == AST_CONSTANT))
{
int var_i = shift_expr->children[0]->type == AST_CONSTANT;
AstNode *tmp = shift_expr->children[var_i]->clone();
stride = result_width;
int const_i = lsb_expr->children[1]->type == AST_CONSTANT;
stride = (int)lsb_expr->children[const_i]->integer;

// Remove multiplication of index by stride.
// FIXME: Counterintuitively, this can yield higher resource usage. Disable for now.
#if 0
div_stride = stride;
AstNode *tmp = lsb_expr->children[1 - const_i]->clone();
delete shift_expr;
shift_expr = tmp;
#endif
}
else if (member_node)
{
Expand All @@ -2419,11 +2430,21 @@ bool AstNode::simplify(bool const_fold, bool in_lvalue, int stage, int width_hin
}
}

// Limit case conditions to possible index range.
int case_width_hint = -1;
bool case_sign_hint = true;
shift_expr->detectSignWidth(case_width_hint, case_sign_hint);
int max_bits = min(case_width_hint, 31 + case_sign_hint);
int max_offset = (1u << (max_bits - case_sign_hint)) - 1;
int min_offset = case_sign_hint ? -(1u << (max_bits - 1)) : 0;

assign = new AstNode(AST_CASE, shift_expr);
for (int i = 0; i < source_width; i += stride) {
for (int i = (1 - result_width)/stride*stride; i < source_width; i += stride) {
int start_bit = source_offset + i;
int end_bit = std::min(start_bit+result_width,source_width) - 1;
AstNode *cond = new AstNode(AST_COND, node_int(start_bit/div_stride));
int end_bit = std::min(start_bit + result_width, source_offset + source_width) - 1;
if (start_bit/div_stride < min_offset || start_bit/div_stride > max_offset)
continue;
AstNode *cond = new AstNode(AST_COND, mkconst_int(start_bit/div_stride, case_sign_hint, case_width_hint));
AstNode *rvalue = clone();
rvalue->delete_children();
if (member_node)
Expand Down

0 comments on commit 52b8b88

Please sign in to comment.