📄 inline.c
字号:
return lExpr;
} // ConvertLocalReferences
/*
* ExpandInlineFunction() - Expand a function inline by duplicating it's statements.
*
*/
static void ExpandInlineFunction(InlineFunData *fFunData, Symbol *funSymb, Symbol *retSymb, expr *fActuals)
{
stmt *body;
stmt *nStmt;
expr *lExpr, *lActual;
Symbol *lFormal;
StmtList newStmts;
// Bump function counter:
fFunData->funInlineIndex = (*fFunData->nextFunInlineIndex)++;
// Duplicate the body of the function:
body = DuplicateStatementTree(funSymb->details.fun.statements);
// Change return statements into assignments:
body = PostApplyToStatements(ConvertReturnStatement, body, retSymb, 0);
// Add numbered copies of expanded function's local variables to current scope,
// and convert any references in copied body of function to new symbols:
SetSymbolFlagsList(ScopeList/*GlobalScope*/, NOT_DUPLICATED);
SetSymbolFlags(fFunData->masterScope->symbols, IN_MASTER_SCOPE);
SetSymbolFlags(fFunData->globalScope->symbols, IN_GLOBAL_SCOPE);
SetSymbolFlags(fFunData->superGlobalScope->symbols, IN_SUPER_GLOBAL_SCOPE);
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// !!! BEGIN !!! Temporary patch for "texobj" parameters!!! Don't assign!!!
#define TYPE_BASE_TEXOBJ_FP30 (TYPE_BASE_FIRST_USER + 2)
lFormal = funSymb->details.fun.params;
lActual = fActuals;
while (lFormal) {
if (GetBase(lFormal->type) == TYPE_BASE_TEXOBJ_FP30) {
assert(lActual->bin.left->common.kind == SYMB_N);
lFormal->tempptr = (void *) lActual->bin.left->sym.symbol;
lFormal->flags = ALREADY_DUPLICATED;
}
lFormal = lFormal->next;
lActual = lActual->bin.right;
}
// !!! END !!! Temporary patch for "texobj" parameters!!! Don't assign!!!
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
PostApplyToExpressions(ConvertLocalReferences, body, fFunData, 0);
// Assign actual parameter expressions to parameters:
newStmts.first = newStmts.last = NULL;
lFormal = funSymb->details.fun.params;
lActual = fActuals;
while (lFormal) {
assert(lActual->common.kind == BINARY_N);
assert(lActual->bin.op == FUN_ARG_OP);
if (((GetQualifiers(lFormal->type) & TYPE_QUALIFIER_IN) ||
!(GetQualifiers(lFormal->type) & TYPE_QUALIFIER_OUT)) &&
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// !!! BEGIN !!! Temporary patch for "texobj" parameters!!! Don't assign!!!
(GetBase(lFormal->type) != TYPE_BASE_TEXOBJ_FP30) &&
// !!! Temporary patch for "texobj" parameters!!! Don't assign!!!
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1)
{
lExpr = (expr *) NewSymbNode(VARIABLE_OP, lFormal);
lExpr = ConvertLocalReferences(lExpr, fFunData, 0);
nStmt = NewSimpleAssignmentStmt(Cg->pLastSourceLoc, lExpr, lActual->bin.left, 1);
AppendStatements(&newStmts, nStmt);
}
lFormal = lFormal->next;
lActual = lActual->bin.right;
}
AppendStatements(&newStmts, body);
// Build assignment statements to copy "out" param's final values to actual parameters:
lFormal = funSymb->details.fun.params;
lActual = fActuals;
while (lFormal) {
if (GetQualifiers(lFormal->type) & TYPE_QUALIFIER_OUT) {
lExpr = (expr *) NewSymbNode(VARIABLE_OP, lFormal);
lExpr = ConvertLocalReferences(lExpr, fFunData, 0);
nStmt = NewSimpleAssignmentStmt(Cg->pLastSourceLoc, lActual->bin.left, lExpr, 0);
AppendStatements(&newStmts, nStmt);
}
lFormal = lFormal->next;
lActual = lActual->bin.right;
}
// Recursively expands calls in newly inlined finction:
body = ExpandInlineFunctionCalls(funSymb->details.fun.locals, newStmts.first, fFunData);
// Do some more stuff here...
// Append the new statements:
AppendStatements(&fFunData->statements, body);
} // ExpandInlineFunction
/*
* ExpandInlineFunctionCallsNode() - Expand inline function calls in an expression.
*
*/
static expr *ExpandInlineFunctionCallsNode(expr *fExpr, void *arg1, int arg2)
{
#define TEMP_ROOT "$temp"
InlineFunData *lFunData = (InlineFunData *) arg1;
Symbol *lSymb, *retSymb;
expr *lExpr;
Type *funType, *retType;
int vname;
switch (fExpr->common.kind) {
case DECL_N:
case SYMB_N:
case CONST_N:
case UNARY_N:
break;
case BINARY_N:
if (fExpr->bin.op == FUN_CALL_OP) {
lExpr = fExpr->bin.left;
if (lExpr->common.kind == SYMB_N) {
lSymb = lExpr->sym.symbol;
assert(IsFunction(lSymb));
if (IsInline(lSymb)) {
funType = lSymb->type;
retType = funType->fun.rettype;
if (!IsVoid(retType)) {
vname = GetNumberedAtom(TEMP_ROOT, (*lFunData->nextTempIndex)++, 4, '\0');
retSymb = DefineVar(&lSymb->loc, lFunData->masterScope, vname, retType);
} else {
retSymb = NULL;
}
if (Cg->options.Comments) {
AddComment(lFunData, Cg->pLastSourceLoc, "Begin inline function");
AddComment(lFunData, Cg->pLastSourceLoc, GetAtomString(atable, lSymb->name));
}
ExpandInlineFunction(lFunData, lSymb, retSymb, fExpr->bin.right);
if (Cg->options.Comments) {
AddComment(lFunData, Cg->pLastSourceLoc, "End inline function");
AddComment(lFunData, Cg->pLastSourceLoc, GetAtomString(atable, lSymb->name));
}
if (retSymb) {
fExpr = (expr *) NewSymbNode(VARIABLE_OP, retSymb);
} else {
fExpr = NULL; // function returning void
}
} else {
// Not done yet: Must continue to traverse call tree to find other
// functions that are called and inline their calls as needed.
// Or some such stuff...
}
}
}
case TRINARY_N:
break;
default:
assert(!"bad kind to ExpandInlineFunctionCallsNode()");
break;
}
return fExpr;
} // ExpandInlineFunctionCallsNode
/*
* ExpandInlineFunctionCallsStmt() - Expand inline function calls in a statement.
*
*/
static stmt *ExpandInlineFunctionCallsStmt(stmt *fStmt, void *arg1, int arg2)
{
InlineFunData *lFunData = (InlineFunData *) arg1;
lFunData->statements.first = NULL;
lFunData->statements.last = NULL;
PostApplyToExpressionsLocal(ExpandInlineFunctionCallsNode, fStmt, arg1, arg2);
if (lFunData->statements.first) {
lFunData->statements.last->commonst.next = fStmt;
fStmt = lFunData->statements.first;
}
lFunData->statements.first = NULL;
lFunData->statements.last = NULL;
return fStmt;
} // ExpandInlineFunctionCallsStmt
/*
* ExpandInlineFunctionCalls() - Recursively walk a program'm call graph from main
* expanding function calls that have the attribute "inline".
*
* Assumes no recursion in inlined functions.
*
*/
stmt *ExpandInlineFunctionCalls(Scope *fscope, stmt *body, InlineFunData *fFunData)
{
int funcount = 0, tempcount = 0;
InlineFunData lFunData;
stmt *lStmt;
if (fFunData) {
lFunData.superGlobalScope = fFunData->superGlobalScope;
lFunData.globalScope = fFunData->globalScope;
lFunData.masterScope = fFunData->masterScope;
lFunData.calleeScope = fscope;
lFunData.nextFunInlineIndex = fFunData->nextFunInlineIndex;
lFunData.nextTempIndex = fFunData->nextTempIndex;
lFunData.funInlineIndex = fFunData->funInlineIndex;
} else {
lFunData.superGlobalScope = fscope->parent->parent;
lFunData.globalScope = fscope->parent;
lFunData.masterScope = fscope;
lFunData.calleeScope = NULL;
lFunData.nextFunInlineIndex = &funcount;
lFunData.nextTempIndex = &tempcount;
lFunData.funInlineIndex = 999;
}
lFunData.funIndex = 0;
lFunData.statements.first = NULL;
lFunData.statements.last = NULL;
lFunData.scratch = NULL;
lStmt = PostApplyToStatements(ExpandInlineFunctionCallsStmt, body, &lFunData, 0);
return lStmt;
} // ExpandInlineFunctionCalls
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// End of inline.c ///////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -