?? compile.c
字號:
break;
case DISCARD_STMT:
lStmt = (stmt *) NewDiscardStmt(&fStmt->commonst.loc, fStmt->discardst.cond);
break;
case COMMENT_STMT:
lStmt = (stmt *) NewCommentStmt(&fStmt->commonst.loc,
GetAtomString(atable, fStmt->commentst.str));
break;
default:
lStmt = fStmt;
assert(!"DuplicateStatement() - not yet finished");
break;
}
PreApplyToExpressions(DuplicateNode, lStmt, arg1, arg2);
} else {
lStmt = NULL;
}
return lStmt;
} // DuplicateStatement
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Named Constant Substitution /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
* ConvertNamedConstantsExpr() - Replace references to names constants with a const node.
*
*/
expr *ConvertNamedConstantsExpr(expr *fExpr, void *arg1, int arg2)
{
Symbol *lSymb;
Type *lType;
expr *lExpr;
int base;
lExpr = fExpr;
if (fExpr) {
switch (fExpr->common.kind) {
case SYMB_N:
// The only named constants are "true" and "false":
lSymb = fExpr->sym.symbol;
lType = lSymb->type;
if (lSymb->kind == CONSTANT_S) {
if (IsScalar(lType)) {
base = GetBase(lType);
switch (base) {
case TYPE_BASE_BOOLEAN:
lExpr = (expr *) NewBConstNode(BCONST_OP, lSymb->details.con.value,
TYPE_BASE_BOOLEAN);
break;
}
}
}
break;
case CONST_N:
case UNARY_N:
case BINARY_N:
case TRINARY_N:
break;
default:
FatalError("bad kind to ConvertNamedConstantsExpr()");
break;
}
} else {
lExpr = NULL;
}
return lExpr;
} // ConvertNamedConstantsExpr
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Remove Empty Statements //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
* RemoveEmptyStatementsStmt() - Expand inline function calls in a statement.
*
*/
stmt *RemoveEmptyStatementsStmt(stmt *fStmt, void *arg1, int arg2)
{
if (fStmt->commonst.kind == EXPR_STMT) {
if (!fStmt->exprst.exp)
fStmt = NULL;
}
return fStmt;
} // RemoveEmptyStatementsStmt
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Remove Empty Statements //////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
typedef struct DebugFunctionData_Rec {
Symbol *color;
Symbol *flag;
Symbol *outConnector;
Symbol *COLSymb;
} DebugFunctionData;
/*
* ConvertDebugCallsStmt() - Expand inline function calls in a statement.
*
*/
stmt *ConvertDebugCallsStmt(stmt *fStmt, void *arg1, int arg2)
{
DebugFunctionData *lDebugData = (DebugFunctionData *) arg1;
expr *eExpr, *sExpr, *lExpr, *mExpr, *bExpr, *rExpr;
stmt *lStmt, *mStmt;
Symbol *lSymb;
if (fStmt->commonst.kind == EXPR_STMT) {
// Look for a call to "debug(float4)":
eExpr = fStmt->exprst.exp;
if (eExpr && eExpr->common.kind == BINARY_N && eExpr->bin.op == FUN_BUILTIN_OP) {
sExpr = eExpr->bin.left;
if (sExpr->common.kind == SYMB_N) {
lSymb = sExpr->sym.symbol;
#define BUILTIN_GROUP_NV30FP_DBG 0
if (lSymb->details.fun.group == BUILTIN_GROUP_NV30FP_DBG &&
lSymb->details.fun.index == 0x444)
{
if (arg2) {
// Turn: "debug(arg);" statements into:
//
// $debug-color@@(!$debug-set) = arg;
// $debug-set = true;
rExpr = eExpr->bin.right->bin.left;
mExpr = GenSymb(lDebugData->flag);
mExpr = GenBoolNot(mExpr);
lExpr = GenSymb(lDebugData->color);
lExpr = GenCondSVAssign(lExpr, mExpr, rExpr, TYPE_BASE_FLOAT, 4);
lStmt = (stmt *) NewExprStmt(Cg->pLastSourceLoc, lExpr);
lExpr = GenSymb(lDebugData->flag);
rExpr = GenBoolConst(1);
lExpr = GenBoolAssign(lExpr, rExpr);
mStmt = (stmt *) NewExprStmt(Cg->pLastSourceLoc, lExpr);
lStmt->commonst.next = mStmt;
fStmt = lStmt;
} else {
// Eliminate: "debug(arg);" statements:
fStmt = NULL;
}
}
}
}
} else if (arg2 && fStmt->commonst.kind == RETURN_STMT) {
rExpr = GenSymb(lDebugData->color);
mExpr = GenSymb(lDebugData->flag);
lExpr = GenSymb(lDebugData->outConnector);
bExpr = GenMember(lDebugData->COLSymb);
lExpr = GenMemberSelector(lExpr, bExpr);
lExpr = GenCondSVAssign(lExpr, mExpr, rExpr, TYPE_BASE_FLOAT, 4);
lStmt = (stmt *) NewExprStmt(Cg->pLastSourceLoc, lExpr);
lStmt->commonst.next = fStmt;
fStmt = lStmt;
}
return fStmt;
} // ConvertDebugCallsStmt
/*
* ConvertDebugCalls() - Convert calls to debug to either assignments to global variables, or
* delete them, depending on the value of DebugFlag. Also defines global variables.
*
*/
stmt *ConvertDebugCalls(SourceLoc *loc, Scope *fScope, stmt *fStmt, int DebugFlag)
{
Symbol *debugColor, *debugSet;
DebugFunctionData debugData;
expr *lExpr, *rExpr;
stmt *lStmt, *rStmt;
StmtList lStatements;
Type *lType;
int vname, COLname;
float fdata[4];
rStmt = fStmt;
if (DebugFlag) {
lStatements.first = lStatements.last = NULL;
//outputSymb = fScope->outConnector;
// 1) Define global vars used by "-debug" mode:
//
// float $debug-color[4];
// bool $debug-set = 0.0f;
vname = AddAtom(atable, "$debug-color");
lType = GetStandardType(TYPE_BASE_FLOAT, 4, 0);
debugColor = DefineVar(loc, fScope, vname, lType);
vname = AddAtom(atable, "$debug-set");
debugSet = DefineVar(loc, fScope, vname, BooleanType);
lExpr = GenSymb(debugSet);
rExpr = GenBoolConst(0);
lExpr = GenBoolAssign(lExpr, rExpr);
lStmt = (stmt *) NewExprStmt(loc, lExpr);
AppendStatements(&lStatements, lStmt);
// 1A) Must initialize $debug-color to something or else the code generator
// gets all bent out of shape:
//
// $debug-color = { 0.0f, 0.0f, 0.0f, .0f };
fdata[0] = fdata[1] = fdata[2] = fdata[3] = 0.0f;
rExpr = GenFConstV(fdata, 4, TYPE_BASE_FLOAT);
lExpr = GenSymb(debugColor);
lExpr = GenVAssign(lExpr, rExpr, TYPE_BASE_FLOAT, 4);
lStmt = (stmt *) NewExprStmt(loc, lExpr);
AppendStatements(&lStatements, lStmt);
// 2) Expand calls to "debug(float4);" into the following code:
//
// $debug-color@@(!$debug-set) = float4;
// $debug-set = true;
debugData.color = debugColor;
debugData.flag = debugSet;
debugData.outConnector = Cg->theHAL->varyingOut;
assert(debugData.outConnector);
COLname = AddAtom(atable, "COL");
lType = debugData.outConnector->type;
assert(IsCategory(lType, TYPE_CATEGORY_CONNECTOR));
debugData.COLSymb = LookUpLocalSymbol(lType->str.members, COLname);
// 3) And add the following statement to the end of the program (i.e. before each
// "return" statement):
//
// output.COL@@($debug-set) = $debug-color;
lStmt = PostApplyToStatements(ConvertDebugCallsStmt, fStmt, &debugData, 1);
AppendStatements(&lStatements, lStmt);
rStmt = lStatements.first;
} else {
rStmt = PostApplyToStatements(ConvertDebugCallsStmt, fStmt, NULL, 0);
}
return rStmt;
} // ConvertDebugCalls
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////// Flatten Chained Assignment Statements ///////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
int IsAssignSVOp(expr *fExpr)
{
int lop;
if (fExpr) {
if (fExpr->common.kind == BINARY_N) {
lop = fExpr->bin.op;
if (lop == ASSIGN_OP || lop == ASSIGN_V_OP || lop == ASSIGN_GEN_OP ||
lop == ASSIGN_MASKED_KV_OP)
{
return 1;
}
}
}
return 0;
} // IsAssignSVOp
int IsAssignCondSVOp(expr *fExpr)
{
int lop;
if (fExpr) {
if (fExpr->common.kind == TRINARY_N) {
lop = fExpr->tri.op;
if (lop == ASSIGN_COND_OP || lop == ASSIGN_COND_V_OP || lop == ASSIGN_COND_SV_OP ||
lop == ASSIGN_COND_GEN_OP)
{
return 1;
}
}
}
return 0;
} // IsAssignCondSVOp
int IsCastOp(expr *fExpr)
{
int lop;
if (fExpr) {
if (fExpr->common.kind == UNARY_N) {
lop = fExpr->un.op;
if (lop == CAST_CS_OP || lop == CAST_CV_OP || lop == CAST_CM_OP)
{
return 1;
}
}
}
return 0;
} // IsCastOp
/*
* NewTmp() - Return a symbol expression for a temp symbol that can
* hold the value of fExpr.
*
*/
symb *NewTmp(const expr *fExpr)
{
Symbol *tmpSym;
Type *tmpType = DupType(fExpr->common.type);
tmpType->co.properties &= ~(TYPE_DOMAIN_MASK | TYPE_QUALIFIER_MASK);
tmpSym = UniqueSymbol(CurrentScope, tmpType, VARIABLE_S);
return NewSymbNode(VARIABLE_OP, tmpSym);
} // NewTmp
/*
* FlattenChainedAssignmentsStmt() - Transform chained assignments into multiple simple
* assignments.
*
* float3 A, C; half B;
*
* Simle case:
*
* A = B = C; (which is equivanemt to:) A = (float) ( B = (half) C ) ;
*
* = = =
* / \ / \ / \
* A (f) >>-->> B (h) A (f)
* \ \ \
* = C B'
* / \
* B (h)
* \
* C
*
* where B' is a duplicate of B.
*
* If B contains any function calls, they must be hoisted prior to this step.
*
*/
stmt *FlattenChainedAssignmentsStmt(stmt *fStmt, void *arg1, int arg2)
{
stmt *bStmt, *rStmt;
expr *assigna, *assignb;
expr *pb, **ppassignb;
if (fStmt->commonst.kind == EXPR_STMT) {
rStmt = fStmt;
assigna = fStmt->exprst.exp;
while (1) {
if (IsAssignSVOp(assigna)) {
ppassignb = &assigna->bin.right;
} else if (IsAssignCondSVOp(assigna)) {
ppassignb = &assigna->tri.arg3;
} else {
break;
}
// Traverse list of type casts, if any:
while (IsCastOp(*ppassignb))
ppassignb = &((**ppassignb).un.arg);
if (IsAssignSVOp(*ppassignb)) {
pb = (**ppassignb).bin.left;
} else if (IsAssignCondSVOp(*ppassignb)) {
pb = (**ppassignb).tri.arg1;
} else {
break;
}
assignb = *ppassignb;
bStmt = (stmt *) NewExprStmt(&fStmt->commonst.loc, assignb);
*ppassignb = PreApplyToNodes(DuplicateNode, pb, arg1, arg2);
bStmt->commonst.next = rStmt;
rStmt = bStmt;
assigna = assignb;
}
} else {
rStmt = fStmt;
}
return rStmt;
} // FlattenChainedAssignmentsStmt
/*
* PutIndexEpxrsInTemps() - Puts all array indicies in temps and
* builds a comma list of assignments of the indices to the
* temporaries.
*
* A[e1]...[eN] -> t1 = e1, ..., tN = eN : A[t1]...[tN]
*/
expr *PutIndexEpxrsInTemps(expr *fExpr)
{
expr *assignments = NULL;
expr *assign;
expr *tmp;
assert(IsArrayIndex(fExpr));
if (IsArrayIndex(fExpr->bin.left))
assignments = PutIndexEpxrsInTemps(fExpr->bin.left);
tmp = (expr *) NewTmp(fExpr->bin.right);
assign = NewSimpleAssignment(Cg->pLastSourceLoc, DupNode(tmp), fExpr->bin.right, 0);
if (!assignments)
assignments = assign;
else
assignments = (expr *) NewBinopNode(COMMA_OP, assignments, assign);
if (IsArrayIndex(fExpr->bin.right))
assignments = (expr *) NewBinopNode(COMMA_OP, assignments,
PutIndexEpxrsInTemps(fExpr->bin.right));
fExpr->bin.right = tmp;
return assignments;
} // PutIndexEpxrsInTemps
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// Expand Increment/Decrement Expressions ////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -