Add a very simple cost model to estimate runtime cost of running code.
This is currently only used to decide whether it's worth doing an "are all lanes running" check at the start of functions--for small functions, it's not worth the overhead. The cost is estimated relatively early in compilation (e.g. before we know if an array access is a scatter/gather or not, before constant folding, etc.), so there are many known shortcomings.
This commit is contained in:
83
stmt.cpp
83
stmt.cpp
@@ -107,6 +107,12 @@ ExprStmt::Print(int indent) const {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ExprStmt::EstimateCost() const {
|
||||
return expr ? expr->EstimateCost() : 0;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// DeclStmt
|
||||
|
||||
@@ -399,6 +405,16 @@ DeclStmt::Print(int indent) const {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
DeclStmt::EstimateCost() const {
|
||||
int cost = 0;
|
||||
for (unsigned int i = 0; i < declaration->declarators.size(); ++i)
|
||||
if (declaration->declarators[i]->initExpr)
|
||||
cost += declaration->declarators[i]->initExpr->EstimateCost();
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IfStmt
|
||||
|
||||
@@ -522,6 +538,14 @@ Stmt *IfStmt::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
IfStmt::EstimateCost() const {
|
||||
return ((test ? test->EstimateCost() : 0) +
|
||||
(trueStmts ? trueStmts->EstimateCost() : 0) +
|
||||
(falseStmts ? falseStmts->EstimateCost() : 0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IfStmt::Print(int indent) const {
|
||||
printf("%*cIf Stmt %s", indent, ' ', doAllCheck ? "DO ALL CHECK" : "");
|
||||
@@ -929,6 +953,13 @@ DoStmt::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
DoStmt::EstimateCost() const {
|
||||
return ((testExpr ? testExpr->EstimateCost() : 0) +
|
||||
(bodyStmts ? bodyStmts->EstimateCost() : 0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DoStmt::Print(int indent) const {
|
||||
printf("%*cDo Stmt", indent, ' ');
|
||||
@@ -1136,6 +1167,20 @@ ForStmt::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ForStmt::EstimateCost() const {
|
||||
bool uniformTest = test ? test->GetType()->IsUniformType() :
|
||||
(!g->opt.disableUniformControlFlow &&
|
||||
!lHasVaryingBreakOrContinue(stmts));
|
||||
|
||||
return ((init ? init->EstimateCost() : 0) +
|
||||
(test ? test->EstimateCost() : 0) +
|
||||
(step ? step->EstimateCost() : 0) +
|
||||
(stmts ? stmts->EstimateCost() : 0) +
|
||||
uniformTest ? COST_UNIFORM_LOOP : COST_VARYING_LOOP);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ForStmt::Print(int indent) const {
|
||||
printf("%*cFor Stmt", indent, ' ');
|
||||
@@ -1190,6 +1235,13 @@ BreakStmt::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
BreakStmt::EstimateCost() const {
|
||||
return doCoherenceCheck ? COST_COHERENT_BREAK_CONTINE :
|
||||
COST_REGULAR_BREAK_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BreakStmt::Print(int indent) const {
|
||||
printf("%*c%sBreak Stmt", indent, ' ', doCoherenceCheck ? "Coherent " : "");
|
||||
@@ -1228,6 +1280,13 @@ ContinueStmt::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ContinueStmt::EstimateCost() const {
|
||||
return doCoherenceCheck ? COST_COHERENT_BREAK_CONTINE :
|
||||
COST_REGULAR_BREAK_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ContinueStmt::Print(int indent) const {
|
||||
printf("%*c%sContinue Stmt", indent, ' ', doCoherenceCheck ? "Coherent " : "");
|
||||
@@ -1274,6 +1333,12 @@ ReturnStmt::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ReturnStmt::EstimateCost() const {
|
||||
return COST_RETURN + (val ? val->EstimateCost() : 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ReturnStmt::Print(int indent) const {
|
||||
printf("%*c%sReturn Stmt", indent, ' ', doCoherenceCheck ? "Coherent " : "");
|
||||
@@ -1319,6 +1384,16 @@ StmtList::TypeCheck() {
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
StmtList::EstimateCost() const {
|
||||
int cost = 0;
|
||||
for (unsigned int i = 0; i < stmts.size(); ++i)
|
||||
if (stmts[i])
|
||||
cost += stmts[i]->EstimateCost();
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
StmtList::Print(int indent) const {
|
||||
printf("%*cStmt List", indent, ' ');
|
||||
@@ -1519,3 +1594,11 @@ PrintStmt::TypeCheck() {
|
||||
values = values->TypeCheck();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PrintStmt::EstimateCost() const {
|
||||
return COST_FUNCALL + (values ? values->EstimateCost() : 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user