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:
Matt Pharr
2011-09-16 15:09:17 -07:00
parent 38fc13d1ab
commit ca87579f23
6 changed files with 263 additions and 9 deletions

View File

@@ -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);
}