?? compile.c
字號:
} // DeconstructMatricesExpr
/*
* DeconstructMatricesStmt()
*
*/
stmt *DeconstructMatricesStmt(stmt *fStmt, void *arg1, int arg2)
{
MData *mdata;
mdata = (MData *) arg1;
mdata->statements.first = mdata->statements.last = NULL;
PostApplyToExpressionsLocal(DeconstructMatricesExpr, fStmt, arg1, arg2);
if (mdata->statements.first) {
mdata->statements.last->commonst.next = fStmt;
fStmt = mdata->statements.first;
}
return fStmt;
} // DeconstructMatricesStmt
/*
* DeconstructMatrices()
*
*/
stmt *DeconstructMatrices(Scope *fscope, stmt *fStmt)
{
MData mdata;
InternalError(Cg->pLastSourceLoc, ERROR___NO_MATRIX_DECONSTRUCTION);
mdata.scope = fscope;
mdata.numtemps = 0;
fStmt = PreApplyToStatements(DeconstructMatricesStmt, fStmt, &mdata, 0);
return fStmt;
} // DeconstructMatrices
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Flatten Struct Assignments ////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
* AssignStructMembers() - Assign individual memebers of one struct to another.
*
*/
static void AssignStructMembers(StmtList *fStatements, int fop, Type *fType, expr *varExpr,
expr *valExpr, expr *condExpr, int VectorCond)
{
expr *lExpr, *mExpr, *rExpr;
int base, len, len2;
Symbol *lSymb;
Type *lType;
stmt *lStmt;
lSymb = fType->str.members->symbols;
while (lSymb) {
len = len2 = 0;
lType = lSymb->type;
if (IsScalar(lType) || IsVector(lType, &len) || IsMatrix(lType, &len, &len2)) {
base = GetBase(lType);
lExpr = DupExpr(varExpr);
mExpr = GenMember(lSymb);
lExpr = GenMemberSelector(lExpr, mExpr);
rExpr = DupExpr(valExpr);
mExpr = GenMember(lSymb);
rExpr = GenMemberSelector(rExpr, mExpr);
if (condExpr != NULL) {
if (len2 > 0) {
lExpr = GenCondGenAssign(lExpr, rExpr, condExpr);
} else if (len > 0) {
if (VectorCond) {
lExpr = GenCondSVAssign(lExpr, rExpr, condExpr, base, len);
} else {
lExpr = GenCondVAssign(lExpr, rExpr, condExpr, base, len);
}
} else {
lExpr = GenCondSAssign(lExpr, rExpr, condExpr, base);
}
lStmt = (stmt *) NewExprStmt(Cg->pLastSourceLoc, lExpr);
} else {
if (len2 > 0) {
lExpr = GenMAssign(lExpr, rExpr, base, len, len2);
} else if (len > 0) {
lExpr = GenVAssign(lExpr, rExpr, base, len);
} else {
lExpr = GenSAssign(lExpr, rExpr, base);
}
lStmt = (stmt *) NewExprStmt(Cg->pLastSourceLoc, lExpr);
}
AppendStatements(fStatements, lStmt);
} else {
switch (GetCategory(lType)) {
case TYPE_CATEGORY_STRUCT:
lExpr = DupExpr(varExpr);
mExpr = GenMember(lSymb);
lExpr = GenMemberSelector(lExpr, mExpr);
rExpr = DupExpr(valExpr);
mExpr = GenMember(lSymb);
rExpr = GenMemberSelector(rExpr, mExpr);
AssignStructMembers(fStatements, fop, lType, lExpr, rExpr, condExpr, VectorCond);
break;
case TYPE_CATEGORY_ARRAY:
// XYZZY Not Done Yet XYZZY //
break;
default:
break;
}
}
lSymb = lSymb->next;
}
} // AssignStructMembers
/*
* FlattenStructAssignment() - Convert struct assignments into multiple assignments of members.
*
*/
stmt *FlattenStructAssignment(stmt *fStmt, void *arg1, int flevel)
{
stmt *rStmt;
expr *eExpr, *lExpr, *rExpr, *cExpr;
int lop, lsubop;
StmtList lStatements;
Type *lType;
if (fStmt) {
switch (fStmt->commonst.kind) {
case EXPR_STMT:
eExpr = fStmt->exprst.exp;
if (IsAssignSVOp(eExpr)) {
lType = eExpr->bin.type;
if (IsStruct(lType)) {
if (IsAssignCondSVOp(eExpr)) {
lop = eExpr->tri.op;
lExpr = eExpr->tri.arg1;
cExpr = eExpr->tri.arg2;
rExpr = eExpr->tri.arg3;
if (IsScalar(cExpr->common.type)) {
AssignStructMembers(&lStatements, lop, lType, lExpr, rExpr, cExpr, 0);
} else {
AssignStructMembers(&lStatements, lop, lType, lExpr, rExpr, cExpr, 1);
}
rStmt = lStatements.first;
} else {
lop = eExpr->bin.op;
lExpr = eExpr->bin.left;
rExpr = eExpr->bin.right;
lsubop = eExpr->bin.subop;
lStatements.first = NULL;
lStatements.last = NULL;
AssignStructMembers(&lStatements, lop, lType, lExpr, rExpr, NULL, 0);
rStmt = lStatements.first;
}
} else {
rStmt = fStmt;
}
} else {
rStmt = fStmt;
}
break;
default:
rStmt = fStmt;
break;
}
} else {
rStmt = fStmt;
}
return rStmt;
} // FlattenStructAssignment
/*
* FlattenStructAssignments() - Convert struct assignments into multiple member assignments.
*
*/
static stmt *FlattenStructAssignments(Scope *fScope, stmt *fStmt)
{
stmt *lStmt;
lStmt = PreApplyToStatements(FlattenStructAssignment, fStmt, NULL, 0);
return lStmt;
} // FlattenStructAssignments
///////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// Flatten If Statements ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
/*
* FlattenIfStatementsStmt() - Convert if statements into conditional assignments.
*
* if (A > B)
* C = D;
* else
* E = F;
*
* becomes:
*
* $if1 = A > B;
* C@@($if1) = D;
* E@@(!$if1) = F;
*
* and:
*
* if (A > B)
* if (C > D)
* E = F;
* else
* G = H;
* else
* if (J > K)
* L = M;
* else
* N = P;
*
* becomes:
*
* $if1 = A > B;
* $ife2 = C > D;
* $if2 = $if1 && $ife2;
* E@@($if2) = F;
* $if2 = $if1 && !$ife2;
* G@@($if2) = H;
* $ife2 = J > K;
* $if2 = !$if1 && $ife2;
* L@@($if2) = M;
* $if2 = !$if1 && !$ife2;
* N@@($if2) = P;
*
* Existing conditional assignments:
*
* A@@XZ = B;
* C@@(D) = E;
*
* become:
*
* A@@({ $if1, 0, $if1, 0 }) = B;
* C@@($if1@xyzw && D) = E; or: C@@($if1 && D) = E;
*
* Issues:
*
* 1) "out" parameters to function calls: not a problem if function calls
* have been previously inlined.
* 2) Assumes "chained" assignments have already been split into simple assignments.
* 3) Assumes all large asignments (structs, matrices, vectors > 4) have been eliminated.
*
*/
typedef struct FlattenIf_Rec {
Scope *funScope;
Symbol *ifSymbTotal; // Current combined if value: "$if2" for level 2, NULL for level 0.
Symbol *ifSymbParent; // Enclosing if's combined value: "$if1" for level 2, NULL for level <= 1.
Symbol *ifSymbLocal; // Current level's simple if value: "$ife2" for level 2
} FlattenIf;
static stmt *FlattenIfStatementsStmt(stmt *fStmt, void *arg1, int flevel)
{
#define IF_ROOT "$if"
#define IF_ROOT_E "$iflocal"
stmt *rStmt, *lStmt, *nStmt;
expr *eExpr, *lExpr, *rExpr, *ifvar, *nExpr, *mExpr, *tExpr;
int level, lop, lsubop, nop, nsubop, vname, mask, len, base, ii;
FlattenIf *lFlatten;
Symbol *lSymbTotal, *lSymbLocal, *ifSymbTotalSave, *ifSymbParentSave;
StmtList lStatements;
Type *lType;
if (fStmt) {
lFlatten = (FlattenIf *) arg1;
level = flevel >= 0 ? flevel : -flevel;
switch (fStmt->commonst.kind) {
case IF_STMT:
// Find $if1 variable(s) for this level:
vname = GetNumberedAtom(IF_ROOT, level + 1, 1, '\0');
lSymbTotal = LookUpSymbol(lFlatten->funScope, vname);
if (!lSymbTotal) {
lSymbTotal = DefineVar(&fStmt->commonst.loc, lFlatten->funScope, vname, BooleanType);
}
if (level > 0) {
vname = GetNumberedAtom(IF_ROOT_E, level + 1, 1, '\0');
lSymbLocal = LookUpSymbol(lFlatten->funScope, vname);
if (!lSymbLocal) {
lSymbLocal = DefineVar(&fStmt->commonst.loc, lFlatten->funScope, vname, BooleanType);
}
} else {
lSymbLocal = lSymbTotal;
}
// Create assignment statement for local expression:
lStatements.first = NULL;
lStatements.last = NULL;
lExpr = GenSymb(lSymbLocal);
lExpr = GenBoolAssign(lExpr, fStmt->ifst.cond);
lStmt = (stmt *) NewExprStmt(&fStmt->commonst.loc, lExpr);
AppendStatements(&lStatements, lStmt);
ifSymbTotalSave = lFlatten->ifSymbTotal;
ifSymbParentSave = lFlatten->ifSymbParent;
lFlatten->ifSymbParent = lFlatten->ifSymbLocal;
lFlatten->ifSymbLocal = lSymbLocal;
lFlatten->ifSymbTotal = lSymbTotal;
// Compute effective Boolean expression if necessary:
if (level > 0) {
lExpr = GenSymb(lFlatten->ifSymbParent);
if (flevel == -1) {
// Top level if's don't create a negated value:
lExpr = GenBoolNot(lExpr);
}
rExpr = GenSymb(lSymbLocal);
rExpr = GenBoolAnd(lExpr, rExpr);
lExpr = GenSymb(lFlatten->ifSymbTotal);
lExpr = GenBoolAssign(lExpr, rExpr);
lStmt = (stmt *) NewExprStmt(&fStmt->commonst.loc, lExpr);
AppendStatements(&lStatements, lStmt);
}
// Walk sub-statements and transform assignments into conditional assignments:
lStmt = fStmt->ifst.thenstmt;
fStmt->ifst.thenstmt = NULL;
while (lStmt) {
nStmt = lStmt->commonst.next;
lStmt->commonst.next = NULL;
lStmt = FlattenIfStatementsStmt(lStmt, arg1, level + 1);
AppendStatements(&lStatements, lStmt);
lStmt = nStmt;
}
if (fStmt->ifst.elsestmt) {
// Compute effective Boolean expression if necessary:
if (level > 0) {
lExpr = GenSymb(lFlatten->ifSymbParent);
if (flevel == -1)
lExpr = GenBoolNot(lExpr);
rExpr = GenSymb(lSymbLocal);
rExpr = GenBoolNot(rExpr);
rExpr = GenBoolAnd(lExpr, rExpr);
lExpr = GenSymb(lFlatten->ifSymbTotal);
lExpr = GenBoolAssign(lExpr, rExpr);
lStmt = (stmt *) NewExprStmt(&fStmt->commonst.loc, lExpr);
AppendStatements(&lStatements, lStmt);
}
lStmt = fStmt->ifst.elsestmt;
fStmt->ifst.elsestmt = NULL;
while (lStmt) {
nStmt = lStmt->commonst.next;
lStmt->commonst.next = NULL;
lStmt = FlattenIfStatementsStmt(lStmt, arg1, -(level + 1));
AppendStatements(&lStatements, lStmt);
lStmt = nStmt;
}
}
lFlatten->ifSymbTotal = ifSymbTotalSave;
lFlatten->ifSymbLocal = lFlatten->ifSymbParent;
lFlatten->ifSymbParent = ifSymbParentSave;
rStmt = lStatements.first;
break;
case EXPR_STMT:
if (level > 0) {
eExpr = fStmt->exprst.exp;
if (IsAssignSVOp(eExpr)) {
lExpr = eExpr->bin.left;
rExpr = eExpr->bin.right;
lop = eExpr->bin.op;
lsubop = eExpr->bin.subop;
lType = eExpr->bin.type;
ifvar = GenSymb(lFlatten->ifSymbTotal);
if (flevel == -1)
ifvar = GenBoolNot(ifvar);
if (lop == ASSIGN_MASKED_KV_OP) {
mask = SUBOP_GET_MASK(lsubop);
len = SUBOP_GET_S(lsubop);
base = SUBOP_GET_T(lsubop);
// Create vector of $if/FALSE values:
mExpr = NULL;
for (ii = 0; ii < len; ii++) {
if (mask & 1) {
tExpr = GenSymb(lFlatten->ifSymbTotal);
} else {
tExpr = GenBoolConst(0);
}
mExpr = GenExprList(mExpr, tExpr, BooleanType);
mask >>= 1;
}
ifvar = (expr *) NewUnopSubNode(VECTOR_V_OP, SUBOP_V(len, TYPE_BASE_BOOLEAN), mExpr);
ifvar->un.type = GetStandardType(TYPE_BASE_BOOLEAN, len, 0);
nop = ASSIGN_COND_V_OP;
nsubop = SUBOP_V(len, base);
} else {
// Normal assign. Convert it to simple conditional assignment:
switch (lop) {
case ASSIGN_OP:
nop = ASSIGN_COND_OP;
nsubop = lsubop;
break;
case ASSIGN_V_OP:
nop = ASSIGN_COND_SV_OP;
nsubop = lsubop;
break;
case ASSIGN_GEN_OP:
nop = ASSIGN_COND_GEN_OP;
nsubop = lsubop;
break;
default:
assert(0);
break;
}
}
nExpr = (expr *) NewTriopSubNode(nop, nsubop, lExpr, ifvar, rExpr);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -