diff --git a/playground/spslr_pinpoint.cpp b/playground/spslr_pinpoint.cpp index 0b9cd84..4abb810 100644 --- a/playground/spslr_pinpoint.cpp +++ b/playground/spslr_pinpoint.cpp @@ -842,22 +842,51 @@ static void emit_named_asm_label_before(SPSLROffsetofCallData::UID uid, rtx_insn char name[128]; snprintf(name, sizeof(name), "%s%lu:\n", SPSLR_OFFSETOF, uid); - /* Build empty operand vectors. */ rtvec no_out = rtvec_alloc(0); rtvec no_in = rtvec_alloc(0); rtvec no_cl = rtvec_alloc(0); const char* empty_constraints = ""; - /* Location: use current insn’s location if available. */ location_t loc = INSN_LOCATION(before); - /* Create a zero-operand, volatile asm insn. */ rtx asmops = gen_rtx_ASM_OPERANDS (VOIDmode, ggc_strdup(name), empty_constraints, 1, no_out, no_in, no_cl, loc); - - /* Emit it right before the target insn. This does NOT affect the CFG. */ emit_insn_before (asmops, before); } +static rtx labeled_cst_mov(SPSLROffsetofCallData::UID uid, rtx dest, Member::OFF ioff, location_t loc) { + char asm_str[128]; + snprintf(asm_str, sizeof(asm_str), "%s%lu:\nmov %1, %0\n", SPSLR_OFFSETOF, uid); + + // rtl.def + // -> DEF_RTL_EXPR(ASM_INPUT, "asm_input", "sL", RTX_EXTRA) -> only string+location in ASM_INPUT + // -> DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEEL", RTX_EXTRA) + + rtx desc_in1 = gen_rtx_ASM_INPUT(SImode, ggc_strdup("i")); + rtvec desc_inputs = gen_rtvec(1, desc_in1); + rtvec inputs = gen_rtvec(1, GEN_INT(ioff)); + + const char* desc_outputs = "=r"; + rtvec outputs = gen_rtvec(1, dest); + + rtvec labels = rtvec_alloc(0); + + rtx asmops = gen_rtx_ASM_OPERANDS(GET_MODE(dest), + ggc_strdup(asm_str), /* template */ + ggc_strdup(desc_outputs), /* output constraint */ + 0, /* output number */ + inputs, /* vector of input RTXs */ + desc_inputs, /* vector of input descriptors */ + labels, /* labels (empty) */ + loc); /* source location */ + + rtx cc_clob = gen_rtx_CLOBBER(VOIDmode, gen_rtx_REG(CCmode, 17)); + + rtvec vec = gen_rtvec (2, gen_rtx_SET(dest, asmops), cc_clob); + rtx parallel = gen_rtx_PARALLEL(VOIDmode, vec); + + return parallel; +} + static void unspec_to_labeled_const(function* fn) { basic_block bb; FOR_EACH_BB_FN(bb, fn) { @@ -893,13 +922,20 @@ static void unspec_to_labeled_const(function* fn) { return; } + // TODO + + PATTERN(insn) = labeled_cst_mov(uid, dest, initial_offset, INSN_LOCATION(insn)); + INSN_CODE(insn) = -1; + df_insn_rescan(insn); + + /* // Generate asm label emit_named_asm_label_before(uid, insn); - /* 2. Replace UNSPEC with constant. */ rtx new_set = gen_rtx_SET(dest, GEN_INT(initial_offset)); PATTERN(insn) = new_set; - INSN_CODE(insn) = -1; /* force re-recognition */ + INSN_CODE(insn) = -1; // force re-recognition + */ std::cout << "Inserted labeled initial member offset " << initial_offset << " for access uid " << uid << "!" << std::endl; @@ -954,18 +990,24 @@ int plugin_init (struct plugin_name_args *plugin_info, struct plugin_gcc_version print_pass_info.pos_op = PASS_POS_INSERT_AFTER; register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &print_pass_info); + /* + TODO + vregs is almost immediately after expand (maybe the first one) + optimizations happen afterwards (e.g. forward propagation in rtl-fwprop1) + */ + struct register_pass_info call_to_unspec_pass_info; call_to_unspec_pass_info.pass = new call_to_unspec_pass(nullptr); - call_to_unspec_pass_info.reference_pass_name = "expand"; + call_to_unspec_pass_info.reference_pass_name = "vregs"; // "expand"; call_to_unspec_pass_info.ref_pass_instance_number = 1; call_to_unspec_pass_info.pos_op = PASS_POS_INSERT_AFTER; register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &call_to_unspec_pass_info); struct register_pass_info unspec_to_lconst_pass_info; unspec_to_lconst_pass_info.pass = new unspec_to_lconst_pass(nullptr); - unspec_to_lconst_pass_info.reference_pass_name = "vregs"; + unspec_to_lconst_pass_info.reference_pass_name = "call_to_unspec"; // "vregs"; unspec_to_lconst_pass_info.ref_pass_instance_number = 1; - unspec_to_lconst_pass_info.pos_op = PASS_POS_INSERT_BEFORE; + unspec_to_lconst_pass_info.pos_op = PASS_POS_INSERT_AFTER; // PASS_POS_INSERT_BEFORE; register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &unspec_to_lconst_pass_info); return 0;