o3: make dispatch LSQ full check more selective
[gem5.git] / SConstruct
index ff36fbccdc26662a47072b8bb3c0d5c2f8970eeb..6a44f3a94a57583d80df47ccd363f5d817adf478 100755 (executable)
@@ -109,6 +109,7 @@ For more details, see:
     raise
 
 # Global Python includes
+import itertools
 import os
 import re
 import subprocess
@@ -567,52 +568,46 @@ else:
     Exit(1)
 
 if main['GCC']:
-    # Check for a supported version of gcc, >= 4.4 is needed for c++0x
-    # support. See http://gcc.gnu.org/projects/cxx0x.html for details
+    # Check for a supported version of gcc. >= 4.6 is chosen for its
+    # level of c++11 support. See
+    # http://gcc.gnu.org/projects/cxx0x.html for details. 4.6 is also
+    # the first version with proper LTO support.
     gcc_version = readCommand([main['CXX'], '-dumpversion'], exception=False)
-    if compareVersions(gcc_version, "4.4") < 0:
-        print 'Error: gcc version 4.4 or newer required.'
+    if compareVersions(gcc_version, "4.6") < 0:
+        print 'Error: gcc version 4.6 or newer required.'
         print '       Installed version:', gcc_version
         Exit(1)
 
     main['GCC_VERSION'] = gcc_version
 
-    # Check for versions with bugs
-    if not compareVersions(gcc_version, '4.4.1') or \
-       not compareVersions(gcc_version, '4.4.2'):
-        print 'Info: Tree vectorizer in GCC 4.4.1 & 4.4.2 is buggy, disabling.'
-        main.Append(CCFLAGS=['-fno-tree-vectorize'])
-
-    # LTO support is only really working properly from 4.6 and beyond
-    if compareVersions(gcc_version, '4.6') >= 0:
-        # Add the appropriate Link-Time Optimization (LTO) flags
-        # unless LTO is explicitly turned off. Note that these flags
-        # are only used by the fast target.
-        if not GetOption('no_lto'):
-            # Pass the LTO flag when compiling to produce GIMPLE
-            # output, we merely create the flags here and only append
-            # them later/
-            main['LTO_CCFLAGS'] = ['-flto=%d' % GetOption('num_jobs')]
-
-            # Use the same amount of jobs for LTO as we are running
-            # scons with, we hardcode the use of the linker plugin
-            # which requires either gold or GNU ld >= 2.21
-            main['LTO_LDFLAGS'] = ['-flto=%d' % GetOption('num_jobs'),
-                                   '-fuse-linker-plugin']
+    # Add the appropriate Link-Time Optimization (LTO) flags
+    # unless LTO is explicitly turned off. Note that these flags
+    # are only used by the fast target.
+    if not GetOption('no_lto'):
+        # Pass the LTO flag when compiling to produce GIMPLE
+        # output, we merely create the flags here and only append
+        # them later/
+        main['LTO_CCFLAGS'] = ['-flto=%d' % GetOption('num_jobs')]
+
+        # Use the same amount of jobs for LTO as we are running
+        # scons with, we hardcode the use of the linker plugin
+        # which requires either gold or GNU ld >= 2.21
+        main['LTO_LDFLAGS'] = ['-flto=%d' % GetOption('num_jobs'),
+                               '-fuse-linker-plugin']
 
     main.Append(TCMALLOC_CCFLAGS=['-fno-builtin-malloc', '-fno-builtin-calloc',
                                   '-fno-builtin-realloc', '-fno-builtin-free'])
 
 elif main['CLANG']:
-    # Check for a supported version of clang, >= 2.9 is needed to
-    # support similar features as gcc 4.4. See
+    # Check for a supported version of clang, >= 3.0 is needed to
+    # support similar features as gcc 4.6. See
     # http://clang.llvm.org/cxx_status.html for details
     clang_version_re = re.compile(".* version (\d+\.\d+)")
     clang_version_match = clang_version_re.search(CXX_version)
     if (clang_version_match):
         clang_version = clang_version_match.groups()[0]
-        if compareVersions(clang_version, "2.9") < 0:
-            print 'Error: clang version 2.9 or newer required.'
+        if compareVersions(clang_version, "3.0") < 0:
+            print 'Error: clang version 3.0 or newer required.'
             print '       Installed version:', clang_version
             Exit(1)
     else:
@@ -726,23 +721,12 @@ if len(swig_version) < 3 or \
     print 'Error determining SWIG version.'
     Exit(1)
 
-min_swig_version = '1.3.34'
+min_swig_version = '2.0.4'
 if compareVersions(swig_version[2], min_swig_version) < 0:
     print 'Error: SWIG version', min_swig_version, 'or newer required.'
     print '       Installed version:', swig_version[2]
     Exit(1)
 
-# Older versions of swig do not play well with more recent versions of
-# gcc due to assumptions on implicit includes (cstddef) and use of
-# namespaces
-if main['GCC'] and compareVersions(gcc_version, '4.6') > 0 and \
-        compareVersions(swig_version[2], '2') < 0:
-    print '\n' + termcap.Yellow + termcap.Bold + \
-        'Warning: SWIG 1.x cause issues with gcc 4.6 and later.\n' + \
-        termcap.Normal + \
-        'Use SWIG 2.x to avoid assumptions on implicit includes\n' + \
-        'and use of namespaces\n'
-
 # Set up SWIG flags & scanner
 swig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS')
 main.Append(SWIGFLAGS=swig_flags)
@@ -876,7 +860,8 @@ if main['M5_BUILD_CACHE']:
 # First we check if python2-config exists, else we use python-config
 python_config = readCommand(['which', 'python2-config'], exception='').strip()
 if not os.path.exists(python_config):
-    python_config = readCommand(['which', 'python-config'], exception='')
+    python_config = readCommand(['which', 'python-config'],
+                                exception='').strip()
 py_includes = readCommand([python_config, '--includes'],
                           exception='').split()
 # Strip the -I from the include folders before adding them to the
@@ -1170,16 +1155,21 @@ main.SConscript('ext/dramsim2/SConscript',
 ###################################################
 
 main['ALL_ISA_LIST'] = all_isa_list
+all_isa_deps = {}
 def make_switching_dir(dname, switch_headers, env):
     # Generate the header.  target[0] is the full path of the output
     # header to generate.  'source' is a dummy variable, since we get the
     # list of ISAs from env['ALL_ISA_LIST'].
     def gen_switch_hdr(target, source, env):
         fname = str(target[0])
-        f = open(fname, 'w')
         isa = env['TARGET_ISA'].lower()
-        print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname))
-        f.close()
+        try:
+            f = open(fname, 'w')
+            print >>f, '#include "%s/%s/%s"' % (dname, isa, basename(fname))
+            f.close()
+        except IOError:
+            print "Failed to create %s" % fname
+            raise
 
     # Build SCons Action object. 'varlist' specifies env vars that this
     # action depends on; when env['ALL_ISA_LIST'] changes these actions
@@ -1190,8 +1180,37 @@ def make_switching_dir(dname, switch_headers, env):
     # Instantiate actions for each header
     for hdr in switch_headers:
         env.Command(hdr, [], switch_hdr_action)
+
+    isa_target = Dir('.').up().name.lower().replace('_', '-')
+    env['PHONY_BASE'] = '#'+isa_target
+    all_isa_deps[isa_target] = None
+
 Export('make_switching_dir')
 
+# all-isas -> all-deps -> all-environs -> all_targets
+main.Alias('#all-isas', [])
+main.Alias('#all-deps', '#all-isas')
+
+# Dummy target to ensure all environments are created before telling
+# SCons what to actually make (the command line arguments).  We attach
+# them to the dependence graph after the environments are complete.
+ORIG_BUILD_TARGETS = list(BUILD_TARGETS) # force a copy; gets closure to work.
+def environsComplete(target, source, env):
+    for t in ORIG_BUILD_TARGETS:
+        main.Depends('#all-targets', t)
+
+# Each build/* switching_dir attaches its *-environs target to #all-environs.
+main.Append(BUILDERS = {'CompleteEnvirons' :
+                        Builder(action=MakeAction(environsComplete, None))})
+main.CompleteEnvirons('#all-environs', [])
+
+def doNothing(**ignored): pass
+main.Append(BUILDERS = {'Dummy': Builder(action=MakeAction(doNothing, None))})
+
+# The final target to which all the original targets ultimately get attached.
+main.Dummy('#all-targets', '#all-environs')
+BUILD_TARGETS[:] = ['#all-targets']
+
 ###################################################
 #
 # Define build environments for selected configurations.
@@ -1300,14 +1319,25 @@ for variant_path in variant_paths:
     # The src/SConscript file sets up the build rules in 'env' according
     # to the configured variables.  It returns a list of environments,
     # one for each variant build (debug, opt, etc.)
-    envList = SConscript('src/SConscript', variant_dir = variant_path,
-                         exports = 'env')
-
-    # Set up the regression tests for each build.
-    for e in envList:
-        SConscript('tests/SConscript',
-                   variant_dir = joinpath(variant_path, 'tests', e.Label),
-                   exports = { 'env' : e }, duplicate = False)
+    SConscript('src/SConscript', variant_dir = variant_path, exports = 'env')
+
+def pairwise(iterable):
+    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+    a, b = itertools.tee(iterable)
+    b.next()
+    return itertools.izip(a, b)
+
+# Create false dependencies so SCons will parse ISAs, establish
+# dependencies, and setup the build Environments serially. Either
+# SCons (likely) and/or our SConscripts (possibly) cannot cope with -j
+# greater than 1. It appears to be standard race condition stuff; it
+# doesn't always fail, but usually, and the behaviors are different.
+# Every time I tried to remove this, builds would fail in some
+# creative new way. So, don't do that. You'll want to, though, because
+# tests/SConscript takes a long time to make its Environments.
+for t1, t2 in pairwise(sorted(all_isa_deps.iterkeys())):
+    main.Depends('#%s-deps'     % t2, '#%s-deps'     % t1)
+    main.Depends('#%s-environs' % t2, '#%s-environs' % t1)
 
 # base help text
 Help('''