Skip to content

Commit 0c725bb

Browse files
committed
Parser: minor optimization
- x**y where y is 0.5 -> sqrt(x) - pow(pow(x,y),z) -> pow(x,y*z) Sync with AMReX-Codes/amrex#4444.
1 parent 29dfef1 commit 0c725bb

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

Src/amrexpr_Parser_Exe.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ parser_compile_exe_size (struct parser_node* node, char*& p, std::size_t& exe_si
3535
// In parser_exe_eval, we push to the stack for NUMBER, SYMBOL, VP, PP.
3636
// In parser_exe_eval, we pop the stack for ADD, SUB, MUL, DIV, F2, and IF.
3737

38+
// Note that for + and * the nodes have been sorted before this function
39+
// is called. So we don't need to worry about cases like f(x) + x.
40+
41+
// Note that there is no PARSER_SUB. a-b is actually a+(-b).
42+
3843
switch (node->type)
3944
{
4045
case PARSER_NUMBER:
@@ -474,6 +479,19 @@ parser_compile_exe_size (struct parser_node* node, char*& p, std::size_t& exe_si
474479
}
475480
exe_size += sizeof(ParserExePOWI);
476481
}
482+
else if (((struct parser_f2*)node)->ftype == PARSER_POW &&
483+
((struct parser_f2*)node)->r->type == PARSER_NUMBER &&
484+
parser_get_number(((struct parser_f2*)node)->r) == 0.5)
485+
{
486+
parser_compile_exe_size(((struct parser_f2*)node)->l, p, exe_size,
487+
max_stack_size, stack_size, local_variables);
488+
if (p) {
489+
auto *t = new(p) ParserExeF1;
490+
p += sizeof(ParserExeF1);
491+
t->ftype = PARSER_SQRT;
492+
}
493+
exe_size += sizeof(ParserExeF1);
494+
}
477495
else
478496
{
479497
int d1 = parser_ast_depth(((struct parser_f2*)node)->l);

Src/amrexpr_Parser_Y.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,16 @@ parser_ast_optimize (struct parser_node* node, std::map<std::string,double>& loc
13071307
node->type = PARSER_DIV;
13081308
parser_set_number(node->l, 1.0);
13091309
}
1310+
else if (((struct parser_f2*)node)->ftype == PARSER_POW &&
1311+
((struct parser_f2*)node)->l->type == PARSER_F2 &&
1312+
((struct parser_f2*)((struct parser_f2*)node)->l)->ftype == PARSER_POW)
1313+
{ // pow(pow(,),)
1314+
std::swap(node->l, node->r);
1315+
std::swap(node->l, node->r->l);
1316+
node->r->type = PARSER_MUL;
1317+
parser_ast_sort(node);
1318+
parser_ast_optimize(node, local_consts);
1319+
}
13101320
break;
13111321
case PARSER_F3:
13121322
parser_ast_optimize(((struct parser_f3*)node)->n1, local_consts);

Tests/Parser2/fn.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,18 @@ double f (int icase, double x, double y, double z)
206206
return pow(x,y+1);
207207
case 97:
208208
return pow(x+1,y);
209+
case 98:
210+
return pow(x,0.5);
211+
case 99:
212+
return pow(pow(x,y),z);
213+
case 100:
214+
return (x+y+z) + (x-y-z);
215+
case 101:
216+
return (x+y+z) - (-x+y-z);
217+
case 102:
218+
return x/y/z*x*y*z;
219+
case 103:
220+
return ((x+y*z-x*y/z-x*y*z-x/y*z-x/y+z*x/y/z*x*y+z*x-y*z));
209221
default:
210222
throw std::runtime_error("Unknown case "+std::to_string(icase));
211223
return 0.0;

0 commit comments

Comments
 (0)