pinpoint plugin uses asm RTL to get through optimizations
This commit is contained in:
parent
c5b4a31970
commit
d17bef1158
@ -842,22 +842,51 @@ static void emit_named_asm_label_before(SPSLROffsetofCallData::UID uid, rtx_insn
|
|||||||
char name[128];
|
char name[128];
|
||||||
snprintf(name, sizeof(name), "%s%lu:\n", SPSLR_OFFSETOF, uid);
|
snprintf(name, sizeof(name), "%s%lu:\n", SPSLR_OFFSETOF, uid);
|
||||||
|
|
||||||
/* Build empty operand vectors. */
|
|
||||||
rtvec no_out = rtvec_alloc(0);
|
rtvec no_out = rtvec_alloc(0);
|
||||||
rtvec no_in = rtvec_alloc(0);
|
rtvec no_in = rtvec_alloc(0);
|
||||||
rtvec no_cl = rtvec_alloc(0);
|
rtvec no_cl = rtvec_alloc(0);
|
||||||
const char* empty_constraints = "";
|
const char* empty_constraints = "";
|
||||||
|
|
||||||
/* Location: use current insn’s location if available. */
|
|
||||||
location_t loc = INSN_LOCATION(before);
|
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);
|
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);
|
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) {
|
static void unspec_to_labeled_const(function* fn) {
|
||||||
basic_block bb;
|
basic_block bb;
|
||||||
FOR_EACH_BB_FN(bb, fn) {
|
FOR_EACH_BB_FN(bb, fn) {
|
||||||
@ -893,13 +922,20 @@ static void unspec_to_labeled_const(function* fn) {
|
|||||||
return;
|
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
|
// Generate asm label
|
||||||
emit_named_asm_label_before(uid, insn);
|
emit_named_asm_label_before(uid, insn);
|
||||||
|
|
||||||
/* 2. Replace UNSPEC with constant. */
|
|
||||||
rtx new_set = gen_rtx_SET(dest, GEN_INT(initial_offset));
|
rtx new_set = gen_rtx_SET(dest, GEN_INT(initial_offset));
|
||||||
PATTERN(insn) = new_set;
|
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
|
std::cout << "Inserted labeled initial member offset " << initial_offset
|
||||||
<< " for access uid " << uid << "!" << std::endl;
|
<< " 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;
|
print_pass_info.pos_op = PASS_POS_INSERT_AFTER;
|
||||||
register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &print_pass_info);
|
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;
|
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.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.ref_pass_instance_number = 1;
|
||||||
call_to_unspec_pass_info.pos_op = PASS_POS_INSERT_AFTER;
|
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);
|
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;
|
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.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.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);
|
register_callback(plugin_info->base_name, PLUGIN_PASS_MANAGER_SETUP, nullptr, &unspec_to_lconst_pass_info);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user