pinpoint plugin uses asm RTL to get through optimizations

This commit is contained in:
York Jasper Niebuhr 2025-10-24 00:33:36 +02:00
parent c5b4a31970
commit d17bef1158

View File

@ -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 insns 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;