def create_trace_tree(state: State, stablestates: List[str]) -> List[List[TraceNodeObj]]: tracetree = ForkTree() basenode = tracetree.insertnode(TraceNodeObj(state)) # Initially get loops from states once nextlist = get_trans_finalstates_loop([basenode], state.gettransitions()) while nextlist: endnodes = [] for nextnode in nextlist: endnodes += tracetree.appenddata(nextnode[1], nextnode[0]) nextlist = [] for node in endnodes: state = node.getdata().get_state() if not [ stateid for stateid in stablestates if state.getstatename() == stateid ]: nextlist += get_trans_finalstates([node], state.gettransitions()) return tracetree.gettraces()
def _genAccessState(self, arch, state: State, verify_ssp: bool = False): transitions = [trans for trans in state.getaccess() if trans.getaccess() and not trans.getinmsg()] \ + state.getevictmiss() trans_dict = MultiDict() for transition in transitions: trans_dict[transition.getguard()] = transition statestr = "" for guard in trans_dict: ruleid = arch + "_" + str(state) + "_" + guard ccle_dot_state = self.ccle + "." + self.iState statestr += "rule \"" + ruleid + "\"" + self.nl statestr += self.tab + ccle_dot_state + " = " + arch + "_" + str( state) + self.nl statestr += self.gen_network_ready_test(trans_dict[guard]) # Add network ready check here if verify_ssp: statestr += " & " + self._LockTest() + self.nl statestr += "==>" + self.nl if verify_ssp: statestr += self._LockAcquire() + self.end statestr += self.tab + self.tSEND + ruleid + "(" + self.cadr + ", m)" + self.end statestr += "endrule" + self.end + self.nl return statestr
def _genArchState(self, arch, state: State): statestr = "case " + arch + "_" + state.getstatename() + ":" + self.nl statestr += "switch " + self.cinmsg + "." + self.cmtype + self.nl transitions = state.getdataack() + state.getremote() + \ [trans for trans in state.getaccess() if trans.getinmsg()] guard_list = [] for transition in transitions: guard_list.append(transition.getguard()) guard_list = list(set(guard_list)) transitions.sort(key=lambda transition: (transition.getguard( ), transition.getcond(), transition.getfinalstate().getstatename())) op_string = "" for guard in guard_list: guard_trans = [ transition for transition in transitions if transition.getguard() == guard ] op_string += self.gen_operation_str(arch, guard_trans) statestr += self._addtabs(op_string, 1) statestr += self.tab + " else return false" + self.end statestr += "endswitch" + self.end return self._addtabs(statestr, 1)
def copy_trace_or_trans_list_rename_states(self, start_state: State, remote_trace: Union[Trace, List[Transition]], old_trans_to_new_trans_map: Dict[int, Transition], old_state_to_new_state_map: Dict[str, State], forbidden_guards: List[str]) \ -> List[Transition]: remote_transitions = remote_trace if isinstance(remote_trace, Trace): remote_transitions = remote_trace.transitions remote_trace_trans_mod = [] moving_start_state = start_state for ind in range(0, len(remote_transitions)): cur_transition = remote_transitions[ind] # Check if the current transition has been copied before cur_trans_hash = cur_transition.get_hash() if cur_trans_hash in old_trans_to_new_trans_map: remote_trace_trans_mod.append( old_trans_to_new_trans_map[cur_trans_hash]) moving_start_state = old_trans_to_new_trans_map[ cur_trans_hash].finalState else: if cur_transition.startState == cur_transition.finalState: new_trans = self._CopyModifyTransition( cur_transition, moving_start_state, moving_start_state) start_state.addtransitions(new_trans) else: final_state = None if ind == len(remote_transitions) - 1: final_state = cur_transition.finalState moving_start_state, new_trans = self.copy_modify_state( moving_start_state, remote_transitions[ind], old_state_to_new_state_map, forbidden_guards, final_state) remote_trace_trans_mod.append(new_trans) old_trans_to_new_trans_map[cur_trans_hash] = new_trans if remote_transitions[0].startState == remote_transitions[ -1].finalState: remote_trace_trans_mod[-1].finalState = start_state remote_trace_trans_mod[0].startState = start_state return remote_trace_trans_mod
def create_cc_dir_states(self, state_tuples: List[CcDirStateTuple]) -> Dict[str, State]: # Detect terminal states, every new state must have an edge that leads to a different new state cc_dir_start_state_tuples: Dict[Tuple[State, State], Tuple[State, State]] = {} cc_dir_final_state_tuples: Dict[Tuple[State, State], Tuple[State, State]] = {} for state_tuple in state_tuples: start_tuple = (state_tuple.ll_dir_start_state, state_tuple.hl_cc_start_state) cc_dir_start_state_tuples[start_tuple] = start_tuple final_tuple = (state_tuple.ll_dir_final_state, state_tuple.hl_cc_final_state) cc_dir_final_state_tuples[final_tuple] = final_tuple # Translate load and store accesses into message types new_access_list = [] accesses = self.low_level.cache.init_state.access for access in accesses: for access_type in self.ll_access_map[access]: new_access_list.append(access_type) evict = self.low_level.cache.init_state.evict cc_dir_states = {} for cc_dir_state_tuple in set(cc_dir_final_state_tuples).intersection(cc_dir_start_state_tuples): state_str = self.new_state_name(str(cc_dir_state_tuple[0]), str(cc_dir_state_tuple[1])) new_state = State(state_str, new_access_list, evict) cc_dir_states[str(new_state)] = new_state return cc_dir_states
def add_immed_request_access(self, state: State) -> None: for transition in state.gettransitions(): # If an access can be performed without awaiting a response, important not request, # it can still make a request if transition.getaccess() in state.get_access_str(): if transition.getoutmsg(): self.request_access.append(transition.getaccess()) else: self.immed_access.append(transition.getaccess()) elif transition.getaccess() in state.get_evict_str(): if transition.getoutmsg(): self.request_evict.append(transition.getaccess()) else: self.immed_evict.append(transition.getaccess()) else: assert "Unrecognized access"
def add_enter_access(self, state: State, traces: TraceSet) -> None: if state not in traces.final_state_dict: return enter_traces = traces.final_state_dict[state] for entry in enter_traces: for access in entry.access: if access: if access in state.get_access_str( ) and access not in self.enter_access: self.enter_access.append(access) elif access in state.get_evict_str( ) and access not in self.enter_evict: self.enter_evict.append(access) else: assert "Unrecognized access"
def convert_statenodes_to_states(transitions: List[Transition], access: List[str], evict: List[str]) -> Dict[str, State]: states = {} statetransmap = sort_states(transitions) for statename in statetransmap: # Create a new state object states.update({statename: State(statename, access, evict)}) states[statename].addtransitions(statetransmap[statename]) return states
def cc_dir_state(rename_state_list: Dict[State, State], state_str: str, state: State) -> State: if state_str not in rename_state_list: cc_dir_state = State(state_str, state.access, state.evict) rename_state_list[state_str] = cc_dir_state return cc_dir_state else: return rename_state_list[state_str]
def _genAccessSendFunc(self, arch: Architecture, state: State): transitions = [trans for trans in state.getaccess() if trans.getaccess() and not trans.getinmsg()] \ + state.getevictmiss() trans_dict = MultiDict() for transition in transitions: trans_dict[transition.getguard()] = transition sendfctstr = "" for guard in trans_dict: ruleid = arch.get_unique_id_str() + "_" + str(state) + "_" + guard sendfctstr += self._genSendFunctionHeader( arch, ruleid, trans_dict[guard]) + self.nl return sendfctstr
def _CopyModifyState(self, startstate, transition): newstate = State( startstate.getstatename() + "_" + transition.getguard(), self.access, self.evict) for datatrans in startstate.getdataack(): newtrans = copy.copy(datatrans) newtrans.setstartstate(newstate) newstate.addtransitions(newtrans) for startset in transition.getfinalstate().getstatesets(): startset.addstartstate(newstate) for endset in startstate.getendstatesets(): endset.addendstate(newstate) # Create vertice startstate.addtransitions( self._CopyModifyTransition(transition, startstate, newstate)) return newstate
def _MergeGivenStates(self, mergestates, transitionmap, statesets): mergestates.sort(key=lambda x: len(x.getstatename())) # mergestates.sort(key=lambda x: len(x.getstatename())) # Make new state newstate = State(mergestates[0].getstatename(), self.access, self.evict) for transition in transitionmap.values(): newstate.addtransitions(transition[0]) # Explore context startstatesets = [] endstatesets = [] for state in mergestates: startstatesets += state.getstartstatesets() endstatesets += state.getendstatesets() startstatesets = list(set(startstatesets)) endstatesets = list(set(endstatesets)) # Remove old states from all state sets for stateset in statesets.values(): stateset.removestates(mergestates) # Now add new state to sets for stateset in startstatesets: stateset.addstartstate(newstate) for stateset in endstatesets: stateset.addendstate(newstate) # Update links for stateset in statesets.values(): for state in stateset.getstates(): for replacestate in mergestates: state.replaceremotestate(replacestate, newstate)
def _CopyState(self, startstate: State, guard, stateset, stablestates, newstates, dummy_state, defer_operations: List[Tuple[Message, List[CommonTree]]] = None): newstate = State( self._CheckStateName( startstate.getstatename() + "__" + guard + "_" + stateset.getstablestate().getstatename(), stateset), self.access, self.evict) newstates.append(newstate) stateset.addendstate(newstate) #newstate.add_tail_list_defer_msg_operations(copy.copy(startstate.get_defer_msg_operation())) if defer_operations: newstate.add_tail_list_defer_msg_operations(defer_operations) for transition in startstate.getdataack(): newtrans = copy.copy(transition) # Emit non deferred messages #newtrans.add_out_msg_list(copy.copy(transition.getoutmsg())) newtrans.setstartstate(newstate) if transition.getstartstate() == transition.getfinalstate(): newtrans.setfinalstate(newstate) else: finalstate = [ finalstate for finalstate in stablestates if finalstate == newtrans.getfinalstate().getstatename() ] if finalstate: newtrans.setfinalstate(dummy_state) else: finalstate = self._CopyState(newtrans.getfinalstate(), guard, stateset, stablestates, newstates, dummy_state, defer_operations) newtrans.setfinalstate(finalstate) newstate.addtransitions(newtrans) return newstate
def _GenerateState(self, fork_state, remote_transition, stablestates, deferfunc): newstates: List[State] = [] finalsets = remote_transition.getfinalstate().getstatesets() if len(finalsets) > 1: print("Attention") return None newtrans = self._DeepCopyModifyTransitionOperation( remote_transition, fork_state, fork_state) # Defer message defer_tuples = deferfunc(remote_transition, newtrans) unique_dummy_state = State("Placeholder") newstate = self._CopyState(fork_state, remote_transition.getguard(), finalsets[0], stablestates, newstates, unique_dummy_state, defer_tuples) newtrans.setfinalstate(newstate) fork_state.addremotemiss(newtrans) # ADD DEFER TRANSITIONS TO THE FIELD SINCE THERE EXIST TRACES THAT NEED TO BE STORED, # THINK ABOUT NOT SINGLE TRANSITION REMOTE REQUESTS # If the remote transition is part of a longer trace, it is deferred # Take the last new_state for newstate in newstates: for transition in newstate.setTrans: if transition.finalState == unique_dummy_state: if defer_tuples: transition.outMsg = copy.copy(transition.outMsg) transition.operation = copy.copy(transition.operation) # Add defer operation to remote_transition for defer_tuple in defer_tuples: transition.addoutmsg(defer_tuple[0]) transition.add_operation_list(defer_tuple[1]) # Set final state to remote_transition final state transition.finalState = remote_transition.finalState return newstate
def cc_dir_loop_transitions(self, state_map_dict: Dict[State, List[State]]) -> List[Transition]: all_transitions = [] for cc_dir_state in state_map_dict: for mapped_single_layer_state in state_map_dict[cc_dir_state]: if str(mapped_single_layer_state) in self.low_level.directory.stable_state_str: continue for transition in mapped_single_layer_state.gettransitions(): if transition.comm_class != CommunicationClassification.resp: continue # if the transition loops if transition.startState == transition.finalState and not transition.access: new_trans = copy.copy(transition) new_state = State(str(cc_dir_state), transition.startState.access, transition.startState.evict) new_trans.startState = new_state new_trans.finalState = new_state all_transitions.append(new_trans) ret_transitions = self.trans_list_hash_reduction(all_transitions) return ret_transitions
def copy_modify_state(self, startstate: State, transition: Transition, old_state_to_new_state_map: Dict[str, State], forbidden_guards: List[str], final_state: [State, None] = None): # If a known final state exists, then if final_state: newstate = final_state if str(final_state) in old_state_to_new_state_map: newstate = old_state_to_new_state_map[str(final_state)] else: new_state_str = startstate.getstatename( ) + "_" + transition.getguard() if new_state_str in old_state_to_new_state_map: newstate = old_state_to_new_state_map[new_state_str] else: newstate = State(new_state_str, self.access, self.evict) old_state_to_new_state_map[new_state_str] = newstate # The new_state replaces the final state so it must possess all local access permissions for trans in transition.startState.setTrans: if str(trans.inMsg) in forbidden_guards: continue if trans.startState == trans.finalState: new_trans = self._CopyModifyTransition( trans, newstate, newstate) newstate.addtransitions(new_trans) for trans in transition.finalState.setTrans: if str(trans.inMsg) in forbidden_guards: continue if trans.startState == trans.finalState: new_trans = self._CopyModifyTransition( trans, newstate, newstate) newstate.addtransitions(new_trans) # The new_state replaces the final state so it must possess all local access permissions for trans in startstate.setTrans: if str(trans.inMsg) in forbidden_guards: continue if trans.startState == trans.finalState: new_trans = self._CopyModifyTransition( trans, newstate, newstate) newstate.addtransitions(new_trans) for startset in transition.getfinalstate().getstatesets(): startset.addstartstate(newstate) for endset in startstate.getendstatesets(): endset.addendstate(newstate) # Create vertice new_trans = self._CopyModifyTransition(transition, startstate, newstate) startstate.addtransitions(new_trans) return newstate, new_trans