diff --git a/configs/common/BPConfig.py b/configs/common/BPConfig.py index 65e6d65a2c..e6fe1f9c06 100644 --- a/configs/common/BPConfig.py +++ b/configs/common/BPConfig.py @@ -86,3 +86,54 @@ def bp_names(): for name, cls in inspect.getmembers(m5.objects, is_bp_class): _bp_classes[name] = cls + +# The same for indirect branch predictors... +# Dictionary of mapping names of real branch predictor models to classes. +_indirect_bp_classes = {} + + +def is_indirect_bp_class(cls): + """Determine if a class is an indirect branch predictor that can be + instantiated""" + + # We can't use the normal inspect.isclass because the ParamFactory + # and ProxyFactory classes have a tendency to confuse it. + try: + return issubclass(cls, m5.objects.IndirectPredictor) and \ + not cls.abstract + except (TypeError, AttributeError): + return False + +def get_indirect(name): + """Get an Indirect BP class from a user provided class name or alias.""" + + try: + indirect_bp_class = _indirect_bp_classes[name] + return indirect_bp_class + except KeyError: + print("%s is not a valid indirect BP model." % (name,)) + sys.exit(1) + +def print_indirect_bp_list(): + """Print a list of available indirect BP classes.""" + + print("Available Indirect BranchPredictor classes:") + doc_wrapper = TextWrapper(initial_indent="\t\t", subsequent_indent="\t\t") + for name, cls in _indirect_bp_classes.items(): + print("\t%s" % name) + + # Try to extract the class documentation from the class help + # string. + doc = inspect.getdoc(cls) + if doc: + for line in doc_wrapper.wrap(doc): + print(line) + +def indirect_bp_names(): + """Return a list of valid Indirect Branch Predictor names.""" + return _indirect_bp_classes.keys() + +# Add all indirect BPs in the object hierarchy. +for name, cls in inspect.getmembers(m5.objects, is_indirect_bp_class): + _indirect_bp_classes[name] = cls + diff --git a/configs/common/Options.py b/configs/common/Options.py index e0d691f6b2..4279b80061 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -64,6 +64,10 @@ def _listHWPTypes(option, opt, value, parser): HWPConfig.print_hwp_list() sys.exit(0) +def _listIndirectBPTypes(option, opt, value, parser): + BPConfig.print_indirect_bp_list() + sys.exit(0) + def _listMemTypes(option, opt, value, parser): MemConfig.print_mem_list() sys.exit(0) @@ -162,12 +166,19 @@ def addCommonOptions(parser): parser.add_option("--list-bp-types", action="callback", callback=_listBPTypes, help="List available branch predictor types") + parser.add_option("--list-indirect-bp-types", + action="callback", callback=_listIndirectBPTypes, + help="List available indirect branch predictor types") parser.add_option("--bp-type", type="choice", default=None, choices=BPConfig.bp_names(), help = """ type of branch predictor to run with (if not set, use the default branch predictor of the selected CPU)""") + parser.add_option("--indirect-bp-type", type="choice", + default="SimpleIndirectPredictor", + choices=BPConfig.indirect_bp_names(), + help = "type of indirect branch predictor to run with") parser.add_option("--list-hwp-types", action="callback", callback=_listHWPTypes, help="List available hardware prefetcher types") diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index d1b623dd14..078ec0f223 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -483,6 +483,11 @@ def run(options, root, testsys, cpu_class): if options.bp_type: bpClass = BPConfig.get(options.bp_type) switch_cpus[i].branchPred = bpClass() + if options.indirect_bp_type: + IndirectBPClass = \ + BPConfig.get_indirect(options.indirect_bp_type) + switch_cpus[i].branchPred.branchPred.indirectBranchPred = \ + IndirectBPClass() # If elastic tracing is enabled attach the elastic trace probe # to the switch CPUs diff --git a/configs/example/fs.py b/configs/example/fs.py index bf6ae45dd2..386421d4f4 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -206,6 +206,11 @@ def build_test_system(np): if options.bp_type: bpClass = BPConfig.get(options.bp_type) test_sys.cpu[i].branchPred = bpClass() + if options.indirect_bp_type: + IndirectBPClass = \ + BPConfig.get_indirect(options.indirect_bp_type) + test_sys.cpu[i].branchPred.indirectBranchPred = \ + IndirectBPClass() test_sys.cpu[i].createThreads() # If elastic tracing is enabled when not restoring from checkpoint and diff --git a/configs/example/se.py b/configs/example/se.py index 4ee0390210..cbebcea5ee 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -240,6 +240,10 @@ for i in range(np): bpClass = BPConfig.get(options.bp_type) system.cpu[i].branchPred = bpClass() + if options.indirect_bp_type: + indirectBPClass = BPConfig.get_indirect(options.indirect_bp_type) + system.cpu[i].branchPred.indirectBranchPred = indirectBPClass() + system.cpu[i].createThreads() system.redirect_paths = redirect_paths(os.path.expanduser(options.chroot))