More denoops
This commit is contained in:
parent
e80f6643dc
commit
fb6fd76d0b
@ -611,6 +611,9 @@ static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST
|
||||
if(n->nodeKind == AST_EXPR_UNARY_OP && n->exprUnOp.operator == UNOP_REF && n->exprUnOp.operand->nodeKind == AST_EXPR_UNARY_OP && n->exprUnOp.operand->exprUnOp.operator == UNOP_DEREF) {
|
||||
// Turn `&*a` into `a`
|
||||
|
||||
// Artificially change type of casted expression to keep types valid for subsequent passes
|
||||
n->exprUnOp.operand->exprUnOp.operand->expression.type = n->expression.type;
|
||||
|
||||
*nptr = n->exprUnOp.operand->exprUnOp.operand;
|
||||
|
||||
*success = true;
|
||||
@ -635,6 +638,15 @@ static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST
|
||||
|
||||
*nptr = n->exprBinOp.operands[0];
|
||||
|
||||
*success = true;
|
||||
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->exprPrim.val == 0) {
|
||||
// Turn `x + 0` into `x`
|
||||
|
||||
// Artificially change type of casted expression to keep types valid for subsequent passes
|
||||
n->exprBinOp.operands[0]->expression.type = n->expression.type;
|
||||
|
||||
*nptr = n->exprBinOp.operands[0];
|
||||
|
||||
*success = true;
|
||||
} else if(n->nodeKind == AST_EXPR_UNARY_OP && n->exprUnOp.operator == UNOP_NOT && n->exprUnOp.operand->nodeKind == AST_EXPR_BINARY_OP && binop_comp_opposite(n->exprUnOp.operand->exprBinOp.operator) != BINOP_WTF) {
|
||||
// Turn `!(a op b)` to `(a !op b)`
|
||||
@ -653,8 +665,31 @@ static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST
|
||||
} else if(n->nodeKind == AST_EXPR_CAST && n->exprCast.what->expression.type->type == TYPE_TYPE_POINTER && n->exprCast.to->type == TYPE_TYPE_POINTER) {
|
||||
// Turn (x as A*) into x, since all pointer types are identical in Nectar's AST
|
||||
|
||||
// Artificially change type of casted expression to keep types valid for subsequent passes
|
||||
n->exprCast.what->expression.type = n->exprCast.to;
|
||||
|
||||
*nptr = n->exprCast.what;
|
||||
|
||||
*success = true;
|
||||
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
// Constant propagation of + operator
|
||||
|
||||
AST *prim = n->exprBinOp.operands[0];
|
||||
prim->expression.type = n->exprBinOp.type;
|
||||
prim->exprPrim.val = n->exprBinOp.operands[0]->exprPrim.val + n->exprBinOp.operands[1]->exprPrim.val;
|
||||
|
||||
*nptr = prim;
|
||||
|
||||
*success = true;
|
||||
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_SUB && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
// Constant propagation of - operator
|
||||
|
||||
AST *prim = n->exprBinOp.operands[0];
|
||||
prim->expression.type = n->exprBinOp.type;
|
||||
prim->exprPrim.val = n->exprBinOp.operands[0]->exprPrim.val - n->exprBinOp.operands[1]->exprPrim.val;
|
||||
|
||||
*nptr = prim;
|
||||
|
||||
*success = true;
|
||||
} else if(n->nodeKind == AST_EXPR_EXT_SIZEOF) {
|
||||
ASTExprPrimitive *prim = calloc(1, sizeof(*prim));
|
||||
@ -709,9 +744,10 @@ void ast_denoop(AST *tlc, AST **node) {
|
||||
}
|
||||
|
||||
/*
|
||||
* The convention correctness pass converts all function calls & definitions to the form that matches
|
||||
* the architecture most closely. For example, arguments (and return values) in cdecl are always
|
||||
* passed as 32-bit integers, even if they are defined as 8-bit or 16-bit in the source.
|
||||
* The convention correctness pass converts all function calls & function sources to the form
|
||||
* hat matches the architecture most closely. For example, arguments (and return values) in
|
||||
* cdecl are always passed as 32-bit integers, even if they are defined as 8-bit or 16-bit in
|
||||
* the source.
|
||||
*
|
||||
* TODO: convert records to proper form also.
|
||||
*/
|
||||
@ -722,17 +758,19 @@ static void convention_correctness_visitor(AST **nptr, AST *stmt, AST *stmtPrev,
|
||||
|
||||
AST *n = *nptr;
|
||||
|
||||
if(n->nodeKind == AST_STMT_DECL && n->stmtDecl.thing->kind == SCOPEITEM_SYMBOL && n->stmtDecl.thing->type->type == TYPE_TYPE_FUNCTION) {
|
||||
Type *type = n->stmtDecl.thing->type;
|
||||
if(n->nodeKind == AST_EXPR_CALL) {
|
||||
Type *type = n->exprCall.what->expression.type;
|
||||
|
||||
assert(n->stmtDecl.expression->exprFunc.chunk->chunk.functionType == type);
|
||||
assert(type->function.ret->type == TYPE_TYPE_PRIMITIVE || type->function.ret->type == TYPE_TYPE_POINTER);
|
||||
assert(type->type == TYPE_TYPE_POINTER);
|
||||
|
||||
type->function.ret = type_prim_cast(type->function.ret, 8 * x86_max_gpr_size());
|
||||
type = type->pointer.of;
|
||||
|
||||
assert(type->type == TYPE_TYPE_FUNCTION);
|
||||
|
||||
for(size_t i = 0; i < type->function.argCount; i++) {
|
||||
assert(type->function.args[i]->type == TYPE_TYPE_PRIMITIVE || type->function.args[i]->type == TYPE_TYPE_POINTER);
|
||||
type->function.args[i] = type_prim_cast(type->function.args[i], 8 * x86_max_gpr_size());
|
||||
if(type->function.args[i]->type == TYPE_TYPE_PRIMITIVE) {
|
||||
n->exprCall.args[i] = ast_cast_expr(n->exprCall.args[i], type_prim_cast(type->function.args[i], 8 * x86_max_gpr_size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user