From d3186ec8ccc198077479f1cf8e97a5bc0dd73fc7 Mon Sep 17 00:00:00 2001 From: "alexander.nutz" Date: Thu, 14 Nov 2024 07:12:56 +0100 Subject: [PATCH] c --- common/common.c | 18 +++++++++++-- common/common.h | 8 ------ ir/ir.h | 15 +++++++++-- ir/ops.cdef | 11 -------- ir/transform/rets_to_args.c | 50 +++++++++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 23 deletions(-) create mode 100644 ir/transform/rets_to_args.c diff --git a/common/common.c b/common/common.c index be72874..8a03b36 100644 --- a/common/common.c +++ b/common/common.c @@ -40,6 +40,18 @@ int vx_Target_parse(vx_Target* dest, const char * str) return 0; } +static bool x86_need_move_ret_to_arg(vx_CU* cu, vx_IrBlock* block, size_t ret_id) +{ + // TODO + return ret_id >= 2; +} + +static bool etca_need_move_ret_to_arg(vx_CU*, vx_IrBlock* block, size_t ret_id) +{ + // TODO + return ret_id >= 1; +} + void vx_Target_info(vx_TargetInfo* dest, vx_Target const* target) { memset(dest, 0, sizeof(vx_TargetInfo)); @@ -50,13 +62,15 @@ void vx_Target_info(vx_TargetInfo* dest, vx_Target const* target) dest->cmov_opt = true; // TODO: target->flags.x86[vx_Target_X86_CMOV]; dest->tailcall_opt = true; dest->ea_opt = true; - } break; + dest->need_move_ret_to_arg = x86_need_move_ret_to_arg; + } break; case vx_TargetArch_ETCA: { dest->cmov_opt = target->flags.etca[vx_Target_ETCA_condExec]; dest->tailcall_opt = true; - } break; + dest->need_move_ret_to_arg = etca_need_move_ret_to_arg; + } break; // add target } diff --git a/common/common.h b/common/common.h index eacf21e..5385bcd 100644 --- a/common/common.h +++ b/common/common.h @@ -77,12 +77,4 @@ typedef struct { /** format: "arch" or "arch:ext"; 0 is ok */ int vx_Target_parse(vx_Target* dest, const char * str); -typedef struct { - bool cmov_opt; - bool tailcall_opt; - bool ea_opt; -} vx_TargetInfo; - -void vx_Target_info(vx_TargetInfo* dest, vx_Target const* target); - #endif //COMMON_H diff --git a/ir/ir.h b/ir/ir.h index 8bdafc3..261e33f 100644 --- a/ir/ir.h +++ b/ir/ir.h @@ -207,8 +207,19 @@ typedef struct { bool if_eval; } vx_OptConfig; -/** single compilation unit */ +typedef struct vx_CU vx_CU; + typedef struct { + bool cmov_opt; + bool tailcall_opt; + bool ea_opt; + bool (*need_move_ret_to_arg)(vx_CU* cu, vx_IrBlock* block, size_t ret_id); +} vx_TargetInfo; + +void vx_Target_info(vx_TargetInfo* dest, vx_Target const* target); + +/** single compilation unit */ +struct vx_CU { vx_Target target; vx_TargetInfo info; @@ -217,7 +228,7 @@ typedef struct { // TODO: rename to symbols vx_CUBlock * blocks; size_t blocks_len; -} vx_CU; +}; /** targetStr is "arch:ext1,ext2" or "arch" */ void vx_CU_init(vx_CU* dest, const char * targetStr); diff --git a/ir/ops.cdef b/ir/ops.cdef index afa7b83..1f7a765 100644 --- a/ir/ops.cdef +++ b/ir/ops.cdef @@ -741,15 +741,4 @@ enum_entry_prefix "VX_IR_OP_" sideEffect true ; - entry MEMSET args "addr: int, size: int, value: int" - debug "memset" - descr "fill every byte from addr to addr+size with value" - inlineCost 3 # bcz call to memset - execCost 4 - endsFlow false - hasEffect true - volatile false - sideEffect true - ; - } diff --git a/ir/transform/rets_to_args.c b/ir/transform/rets_to_args.c new file mode 100644 index 0000000..1c55dd9 --- /dev/null +++ b/ir/transform/rets_to_args.c @@ -0,0 +1,50 @@ +#include "../passes.h" + +void vx_tra_move_rets_to_arg(vx_CU* cu, vx_IrBlock* block) +{ + assert(block->is_root); + + vx_IrType* ptrTy = vx_ptrType(block).ptr; + + vx_IrTypedVar* newArgs = malloc(sizeof(vx_IrTypedVar) * block->outs_len); + size_t newArgs_count = 0; + + vx_IrVar* newRets = malloc(sizeof(vx_IrVar) * block->outs_len); + size_t newRets_count = 0; + + for (size_t i = 0; i < block->outs_len; i ++) + { + vx_IrVar var = block->outs[i]; + + if (!cu->info.move_ret_to_arg(cu, block, i)) { + newRets[newRets_count ++] = var; + continue; + } + + vx_IrOp* mov = vx_IrBlock_addOpBuilding(block); + vx_IrOp_init(mov, VX_IR_OP_STORE, block); + + vx_IrVar resVar = vx_IrBlock_newVar(block, mov); + newArgs[newArgs_count ++] = (vx_IrTypedVar) { .var = resVar, .type = ptrTy }; + + vx_IrOp_addParam_s(mov, VX_IR_NAME_ADDR, VX_IR_VALUE_VAR(resVar)); + vx_IrOp_addParam_s(mov, VX_IR_NAME_VALUE, VX_IR_VALUE_VAR(var)); + } + + if (newArgs_count == 0) + return; + + free(block->outs); + block->outs = newRets; + block->outs_len = newRets_count; + + // TODO: multiple insert function + vx_IrTypedVar* oldIns = block->ins; + block->ins = malloc(sizeof(vx_IrTypedVar) * (block->ins_len + newArgs_count)); + memcpy(block->ins, newArgs, sizeof(vx_IrTypedVar) * newArgs_count); + memcpy(block->ins + newArgs_count, oldIns, sizeof(vx_IrTypedVar) * block->ins_len); + block->ins_len += newArgs_count; + free(oldIns); + + free(newArgs); +}