Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New fetch nt btb miss #145

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c20b268
initial commit
chestercai1995 Aug 24, 2022
62a2f54
new inst to support verilator
chestercai1995 Aug 24, 2022
df8d141
decode early recovery for btb misses
chestercai1995 Aug 29, 2022
2049e53
probably correct implemention, need to clean up
chestercai1995 Sep 6, 2022
138c88c
something in broken in the baseline
chestercai1995 Sep 13, 2022
160fcfc
need to clean up, this should be a working version of btb fetch non t…
chestercai1995 Oct 4, 2022
d251d78
cleaning up printf
chestercai1995 Oct 4, 2022
f364030
btb fetch nt path done
chestercai1995 Oct 15, 2022
e4a8f7c
some cleanup
chestercai1995 Dec 8, 2022
7659f3c
some more cleanup
chestercai1995 Dec 8, 2022
e4fec36
clean up, removing all the cbr target at exec
chestercai1995 Dec 10, 2022
768cbde
minor changes in icache stage to follow cmp address, more comments in…
chestercai1995 Dec 10, 2022
7b4b68d
making make release work
chestercai1995 Dec 12, 2022
8ab4434
checking cmake and gcc version
chestercai1995 Dec 12, 2022
6721fb6
more version checks
chestercai1995 Dec 17, 2022
9cd13ef
more version checks
chestercai1995 Dec 17, 2022
5b61db7
getting rid of the version checks in the makefile
chestercai1995 Dec 17, 2022
237b654
adding fcommon flag for gcc
chestercai1995 Dec 17, 2022
dad192d
revertting the fcommon flag
chestercai1995 Dec 17, 2022
06bb4d9
add link option fcommon
chestercai1995 Dec 17, 2022
2813065
moving globals variables to the proper .c files
chestercai1995 Dec 17, 2022
7a2cbb6
remove the trace file defination in uop generator.c
chestercai1995 Dec 17, 2022
be923c5
making each global variable unique
chestercai1995 Dec 19, 2022
6fe4cff
making global variables static if it's only intended to be used in on…
chestercai1995 Dec 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bin/scarab_globals/batch_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,4 +347,4 @@ def run_phase(self, phase, dep_ids):
def run(self):
ids = []
for phase in self.phase_list:
ids = self.run_phase(phase, ids)
ids = self.run_phase(phase, ids)
192 changes: 160 additions & 32 deletions src/bp/bp.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,21 @@ void init_bp_recovery_info(uns8 proc_id,

void bp_sched_recovery(Bp_Recovery_Info* bp_recovery_info, Op* op,
Counter cycle, Flag late_bp_recovery,
Flag force_offpath) {
Flag decode_bp_recovery, Flag force_offpath) {
ASSERT(op->proc_id, bp_recovery_info->proc_id == op->proc_id);
ASSERT(op->proc_id, !(late_bp_recovery && decode_bp_recovery));

if(bp_recovery_info->recovery_cycle == MAX_CTR ||
op->op_num <= bp_recovery_info->recovery_op_num) {
const Addr next_fetch_addr = op->oracle_info.npc;
const uns latency = late_bp_recovery ? LATE_BP_LATENCY :
1 + EXTRA_RECOVERY_CYCLES;
DEBUG(
bp_recovery_info->proc_id,
"Recovery signaled for op_num:%s @ 0x%s next_fetch:0x%s offpath:%d\n",
unsstr64(op->op_num), hexstr64s(op->inst_info->addr),
hexstr64s(next_fetch_addr), op->off_path);
if(op->oracle_info.recovery_sch) {
DEBUG(
op->proc_id,
"ASSERT: op num %llu, late rec %d, decode bp %d, force offpath %d\n",
op->op_num, late_bp_recovery, decode_bp_recovery, force_offpath);
}
ASSERT(op->proc_id, !op->oracle_info.recovery_sch);
op->oracle_info.recovery_sch = TRUE;
bp_recovery_info->recovery_cycle = cycle + latency;
Expand All @@ -153,16 +155,39 @@ void bp_sched_recovery(Bp_Recovery_Info* bp_recovery_info, Op* op,
bp_recovery_info->recovery_inst_uid = op->inst_uid;
bp_recovery_info->wpe_flag = FALSE;
bp_recovery_info->late_bp_recovery = late_bp_recovery;
bp_recovery_info->decode_recovery = decode_bp_recovery;

if(force_offpath) {
ASSERT(op->proc_id, late_bp_recovery);
bp_recovery_info->recovery_fetch_addr = op->oracle_info.late_pred_npc;
bp_recovery_info->recovery_info.new_dir = op->oracle_info.late_pred;
ASSERT(op->proc_id, late_bp_recovery || decode_bp_recovery);
if(USE_LATE_BP) {
bp_recovery_info->recovery_fetch_addr = op->oracle_info.late_pred_npc;
bp_recovery_info->recovery_info.new_dir = op->oracle_info.late_pred;
} else {
ASSERT(op->proc_id,
op->oracle_info.pred_target_known_npc == op->oracle_info.npc);
bp_recovery_info->recovery_fetch_addr =
op->oracle_info.pred_target_known_npc;
bp_recovery_info->recovery_info.new_dir = op->oracle_info.pred;
}
ASSERT(op->proc_id,
bp_recovery_info->recovery_fetch_addr != op->oracle_info.npc);
bp_recovery_info->recovery_force_offpath = TRUE;
bp_recovery_info->late_bp_recovery_wrong = TRUE;
} else {
bp_recovery_info->late_bp_recovery_wrong = FALSE;
}
DEBUG(
bp_recovery_info->proc_id,
"Recovery signaled for op_num:%s @ 0x%s next_fetch:0x%s offpath:%d\n",
unsstr64(op->op_num), hexstr64s(op->inst_info->addr),
hexstr64s(bp_recovery_info->recovery_fetch_addr),
bp_recovery_info->recovery_force_offpath);
} else {
DEBUG(bp_recovery_info->proc_id,
"Recovery dropped for opnum %llu, "
"because of existing recovery for opnum %llu on cycle %llu\n",
op->op_num, bp_recovery_info->recovery_op_num,
bp_recovery_info->recovery_cycle);
}
}

Expand All @@ -187,6 +212,10 @@ void bp_sched_redirect(Bp_Recovery_Info* bp_recovery_info, Op* op,
ASSERT(bp_recovery_info->proc_id, bp_recovery_info->proc_id == op->proc_id);
ASSERT_PROC_ID_IN_ADDR(op->proc_id,
bp_recovery_info->redirect_op->oracle_info.pred_npc);
} else {
DEBUG(op->proc_id,
"Dropping Redirect due to an earlier redirct on op %llu\n",
bp_recovery_info->redirect_op_num);
}
ASSERT(bp_recovery_info->proc_id, bp_recovery_info->proc_id == op->proc_id);
ASSERT_PROC_ID_IN_ADDR(op->proc_id,
Expand Down Expand Up @@ -312,13 +341,16 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {

// {{{ special case--system calls
if(op->table_info->cf_type == CF_SYS) {
op->oracle_info.pred = TAKEN;
op->oracle_info.misfetch = FALSE;
op->oracle_info.mispred = FALSE;
op->oracle_info.late_misfetch = FALSE;
op->oracle_info.late_mispred = FALSE;
op->oracle_info.btb_miss = FALSE;
op->oracle_info.no_target = FALSE;
op->oracle_info.pred = TAKEN;
op->oracle_info.misfetch = FALSE;
op->oracle_info.mispred = FALSE;
op->oracle_info.fetch_mispred = FALSE;
op->oracle_info.current_mispred = FALSE;
op->oracle_info.late_misfetch = FALSE;
op->oracle_info.fetch_late_mispred = FALSE;
op->oracle_info.late_mispred = FALSE;
op->oracle_info.btb_miss = FALSE;
op->oracle_info.no_target = FALSE;
ASSERT_PROC_ID_IN_ADDR(op->proc_id, op->oracle_info.npc);
op->oracle_info.pred_npc = op->oracle_info.npc;
op->oracle_info.late_pred_npc = op->oracle_info.npc;
Expand Down Expand Up @@ -351,6 +383,9 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
}
// }}}

const Addr pc_plus_offset = ADDR_PLUS_OFFSET(
op->inst_info->addr, op->inst_info->trace_info.inst_size);

// {{{ handle predictions for individual cf types
switch(op->table_info->cf_type) {
case CF_BR:
Expand Down Expand Up @@ -410,6 +445,11 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
pred_target = ibp_target;
op->oracle_info.no_target = FALSE;
op->oracle_info.ibp_miss = FALSE;
} else if(FETCH_NT_AFTER_BTB_MISS &&
op->oracle_info.npc == pc_plus_offset) {
pred_target = pc_plus_offset;
op->oracle_info.no_target = FALSE;
op->oracle_info.ibp_miss = FALSE;
} else
op->oracle_info.ibp_miss = TRUE;

Expand All @@ -428,8 +468,14 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
pred_target = ibp_target;
op->oracle_info.no_target = FALSE;
op->oracle_info.ibp_miss = FALSE;
} else
} else if(FETCH_NT_AFTER_BTB_MISS &&
op->oracle_info.npc == pc_plus_offset) {
pred_target = pc_plus_offset;
op->oracle_info.no_target = FALSE;
op->oracle_info.ibp_miss = FALSE;
} else {
op->oracle_info.ibp_miss = TRUE;
}
}
if(ENABLE_CRS)
CRS_REALISTIC ? bp_crs_realistic_push(bp_data, op) :
Expand Down Expand Up @@ -481,18 +527,33 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
bp_data->late_bp->spec_update_func(op);
}

const Addr pc_plus_offset = ADDR_PLUS_OFFSET(
op->inst_info->addr, op->inst_info->trace_info.inst_size);
Addr bp_prediction, fetch_prediction;
bp_prediction = op->oracle_info.pred ? pred_target : pc_plus_offset;
op->oracle_info.pred_target_known_npc = bp_prediction;
fetch_prediction = bp_prediction;

const Addr prediction = op->oracle_info.pred ? pred_target : pc_plus_offset;
op->oracle_info.pred_npc = prediction;
if(FETCH_NT_AFTER_BTB_MISS) {
fetch_prediction = (op->oracle_info.pred && !op->oracle_info.btb_miss) ?
pred_target :
pc_plus_offset;
}
op->oracle_info.pred_npc = fetch_prediction;
ASSERT_PROC_ID_IN_ADDR(op->proc_id, op->oracle_info.pred_npc);
// If the direction prediction is wrong, but next address happens to be right
// anyway, do not treat this as a misprediction.
op->oracle_info.mispred = (op->oracle_info.pred != op->oracle_info.dir) &&
(prediction != op->oracle_info.npc);
(bp_prediction != op->oracle_info.npc);
op->oracle_info.misfetch = !op->oracle_info.mispred &&
prediction != op->oracle_info.npc;
fetch_prediction != op->oracle_info.npc;
// if(FETCH_NT_AFTER_BTB_MISS){
// op->oracle_info.misfetch = !op->oracle_info.mispred &&
// !op->oracle_info.btb_miss &&
// bp_prediction != op->oracle_info.npc;
//}
// else{
// op->oracle_info.misfetch = !op->oracle_info.mispred &&
// bp_prediction != op->oracle_info.npc;
//}

if(USE_LATE_BP) {
const Addr late_prediction = op->oracle_info.late_pred ? pred_target :
Expand All @@ -501,10 +562,58 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
op->oracle_info.late_mispred = (op->oracle_info.late_pred !=
op->oracle_info.dir) &&
(late_prediction != op->oracle_info.npc);
op->oracle_info.late_misfetch = !op->oracle_info.late_mispred &&
late_prediction != op->oracle_info.npc;
if(FETCH_NT_AFTER_BTB_MISS) {
op->oracle_info.late_misfetch = !op->oracle_info.late_mispred &&
!op->oracle_info.btb_miss &&
late_prediction != op->oracle_info.npc;
} else {
op->oracle_info.late_misfetch = !op->oracle_info.late_mispred &&
late_prediction != op->oracle_info.npc;
}
if(FETCH_NT_AFTER_BTB_MISS && op->oracle_info.btb_miss &&
op->oracle_info.late_pred) {
// in during a btb miss, predicted taken branch will be overriden with
// predicted not taken
if(!op->oracle_info.dir) {
// predicted taken, actually not taken
// btb miss will force this to be a not taken prediction
// therefore making it a correct prediction
op->oracle_info.fetch_late_mispred = FALSE;
} else if(op->oracle_info.dir && op->oracle_info.npc != pc_plus_offset) {
// predicted taken, actually taken
// btb miss will force this to be a not taken prediction
// therefore making it a incorrect prediction
op->oracle_info.fetch_late_mispred = TRUE;
} else {
op->oracle_info.fetch_late_mispred = FALSE;
}
} else {
op->oracle_info.fetch_late_mispred = op->oracle_info.late_mispred;
}
}

if(FETCH_NT_AFTER_BTB_MISS && op->oracle_info.btb_miss &&
op->oracle_info.pred) {
// in during a btb miss, predicted taken branch will be overriden with
// predicted not taken
if(!op->oracle_info.dir) {
// predicted taken, actually not taken
// btb miss will force this to be a not taken prediction
// therefore making it a correct prediction
op->oracle_info.fetch_mispred = FALSE;
} else if(op->oracle_info.dir && op->oracle_info.npc != pc_plus_offset) {
// predicted taken, actually taken
// btb miss will force this to be a not taken prediction
// therefore making it a incorrect prediction
op->oracle_info.fetch_mispred = TRUE;
} else {
op->oracle_info.fetch_mispred = FALSE;
}
} else {
op->oracle_info.fetch_mispred = op->oracle_info.mispred;
}
op->oracle_info.current_mispred = op->oracle_info.fetch_mispred;

op->bp_cycle = cycle_count;

// {{{ stats and debugging
Expand Down Expand Up @@ -558,14 +667,26 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
hexstr64s(addr), op->oracle_info.btb_miss);

DEBUG(bp_data->proc_id,
"BP: op_num:%s off_path:%d cf_type:%s addr:%s p_npc:%s "
"t_npc:0x%s btb_miss:%d mispred:%d misfetch:%d no_tar:%d\n",
"BP: op_num:%s off_path:%d cf_type:%s addr:%s bp_npc:%s "
"t_npc:0x%s bp_dir:%d t_dir:%d btb_miss:%d f_mispred:%d "
"mispred:%d misfetch:%d "
"no_tar:%d\n",
unsstr64(op->op_num), op->off_path,
cf_type_names[op->table_info->cf_type], hexstr64s(op->inst_info->addr),
hexstr64s(prediction), hexstr64s(op->oracle_info.npc),
op->oracle_info.btb_miss, op->oracle_info.mispred,
hexstr64s(bp_prediction), hexstr64s(op->oracle_info.npc),
op->oracle_info.pred, op->oracle_info.dir, op->oracle_info.btb_miss,
op->oracle_info.fetch_mispred, op->oracle_info.mispred,
op->oracle_info.misfetch, op->oracle_info.no_target);

if(USE_LATE_BP)
DEBUG(bp_data->proc_id,
"LATE_BP: late_mispred:%d late_misfetch:%d late_pred:%d, "
"late_npc:%llx\n",
op->oracle_info.late_mispred, op->oracle_info.late_misfetch,
op->oracle_info.late_pred, op->oracle_info.late_pred_npc);
if(op->oracle_info.late_mispred && !op->oracle_info.mispred)
DEBUG(bp_data->proc_id, "interesting!\n");

if(ENABLE_BP_CONF && IS_CONF_CF(op)) {
bp_data->br_conf->pred_func(op);

Expand Down Expand Up @@ -593,7 +714,7 @@ Addr bp_predict_op(Bp_Data* bp_data, Op* op, uns br_num, Addr fetch_addr) {
DEBUG(bp_data->proc_id, "low_conf_count:%d \n", td->td_info.low_conf_count);
}

return prediction;
return fetch_prediction;
}


Expand All @@ -606,8 +727,15 @@ void bp_target_known_op(Bp_Data* bp_data, Op* op) {
ASSERT(bp_data->proc_id, op->table_info->cf_type);

// if it was a btb miss, it is time to write it into the btb
if(op->oracle_info.btb_miss)
bp_data->bp_btb->update_func(bp_data, op);
if(op->oracle_info.btb_miss) {
if(BTB_ONLY_INSERT_TAKEN_BR) {
if(op->oracle_info.dir) {
bp_data->bp_btb->update_func(bp_data, op);
}
} else {
bp_data->bp_btb->update_func(bp_data, op);
}
}

// special case updates
switch(op->table_info->cf_type) {
Expand Down
4 changes: 3 additions & 1 deletion src/bp/bp.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ typedef struct Bp_Recovery_Info_struct {
// prediction.
Flag late_bp_recovery_wrong; // TRUE if recovery is due to a late branch
// prediction that is wrong.
Flag decode_recovery; // TRUE if recovery is due to a redirect
// from a btb miss at decode

} Bp_Recovery_Info;

Expand Down Expand Up @@ -273,7 +275,7 @@ void set_bp_recovery_info(Bp_Recovery_Info* new_bp_recovery_info);
void init_bp_recovery_info(uns8, Bp_Recovery_Info*);
void bp_sched_recovery(Bp_Recovery_Info* bp_recovery_info, Op* op,
Counter cycle, Flag late_bp_recovery,
Flag force_offpath);
Flag decode_bp_recovery, Flag force_offpath);
void bp_sched_redirect(Bp_Recovery_Info*, Op*, Counter);

void init_bp_data(uns8, Bp_Data*);
Expand Down
41 changes: 34 additions & 7 deletions src/cmp_model.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@

#include "freq.h"

Flag perf_pred_started = FALSE;
Flag perf_pred_started = FALSE;
Cmp_Model cmp_model;

/**************************************************************************************/
/* Static prototypes */
Expand Down Expand Up @@ -318,22 +319,48 @@ void cmp_recover() {
bp_recovery_info->recovery_cycle = MAX_CTR;
bp_recovery_info->redirect_cycle = MAX_CTR;

Op* op = bp_recovery_info->recovery_op;
Cf_Type cf = op->table_info->cf_type;

bp_recover_op(g_bp_data, bp_recovery_info->recovery_cf_type,
&bp_recovery_info->recovery_info);

if(USE_LATE_BP && bp_recovery_info->late_bp_recovery) {
Op* op = bp_recovery_info->recovery_op;
op->oracle_info.pred = op->oracle_info.late_pred;
op->oracle_info.pred_npc = op->oracle_info.late_pred_npc;
op->oracle_info.pred = op->oracle_info.late_pred;
op->oracle_info.pred_npc = op->oracle_info.late_pred_npc;
op->oracle_info.current_mispred = op->oracle_info.late_mispred;
op->oracle_info.misfetch = op->oracle_info.late_misfetch;
ASSERT_PROC_ID_IN_ADDR(op->proc_id, op->oracle_info.pred_npc);
op->oracle_info.mispred = op->oracle_info.late_mispred;
op->oracle_info.misfetch = op->oracle_info.late_misfetch;

// Reset to FALSE to allow for another potential recovery after the branch
// is resolved when executed.
op->oracle_info.recovery_sch = FALSE;
}

if(bp_recovery_info->decode_recovery) {
if(cf == CF_BR || cf == CF_CALL) {
// uncond branches, cannot misprecit anymore after decode
// op->oracle_info.mispred = FALSE;
op->oracle_info.misfetch = FALSE;
op->oracle_info.current_mispred = FALSE;
} else {
ASSERT(op->proc_id, REDIRECT_COND_BTB_MISS_AT_DECODE);
// conditional, redirect base on the latest prediction

if(USE_LATE_BP) {
op->oracle_info.pred = op->oracle_info.late_pred;
op->oracle_info.pred_npc = op->oracle_info.late_pred_npc;
op->oracle_info.misfetch = op->oracle_info.late_misfetch;
op->oracle_info.current_mispred = op->oracle_info.late_mispred;
} else {
op->oracle_info.current_mispred = op->oracle_info.mispred;
}
}
if(op->oracle_info.current_mispred) {
// only allow another recovery if this is still a mispred
op->oracle_info.recovery_sch = FALSE;
}
}

recover_thread(td, bp_recovery_info->recovery_fetch_addr,
bp_recovery_info->recovery_op_num,
bp_recovery_info->recovery_inst_uid,
Expand Down
Loading