config: add an option to list and select indirect branch predictor
authorJairo Balart <jairo.balart@metempsy.com>
Mon, 7 Jan 2019 06:45:14 +0000 (07:45 +0100)
committerJairo Balart <jairo.balart@metempsy.com>
Mon, 13 May 2019 11:44:08 +0000 (11:44 +0000)
Change-Id: I9a855d36de7d95b7785ff8a897899037cea6a3d8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/15320
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
configs/common/BPConfig.py
configs/common/Options.py
configs/common/Simulation.py
configs/example/fs.py
configs/example/se.py

index 65e6d65a2c1237dcbc8646ec6fc0cf73cc1c1c9b..e6fe1f9c069ef665bfaaeb47f91c0008d9e18341 100644 (file)
@@ -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
+
index e0d691f6b241652d4cc2a2457190e0be0ca7575e..4279b80061912d6a77ea95b3230368759b035fd0 100644 (file)
@@ -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")
index d1b623dd1406ad3b4ec6371b2696adea2b1325b4..078ec0f2232e31618d3995f290b7280b817cd24e 100644 (file)
@@ -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
index bf6ae45dd23ed816e612f4d0bba7bd8911e50177..386421d4f43a0c7b617393dde18621439c218eba 100644 (file)
@@ -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
index 4ee039021096f0d0da82e5ca419ffb1c9d8b3fb3..cbebcea5eefada10480215e2e8f2a12e7a1be264 100644 (file)
@@ -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))