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];
|
||||
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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user