diff -r 5f0321c03a26 -r faeddb9fb678 SConstruct --- a/SConstruct Mon Jul 02 08:21:53 2012 -0400 +++ b/SConstruct Mon Jul 02 13:57:16 2012 +0100 @@ -165,6 +165,8 @@ help='Override which build_opts file to use for defaults') AddLocalOption('--ignore-style', dest='ignore_style', action='store_true', help='Disable style checking hooks') +AddLocalOption('--lto', dest='lto', action='store_true', + help='Enable Link-Time Optimization') AddLocalOption('--update-ref', dest='update_ref', action='store_true', help='Update test reference outputs') AddLocalOption('--verbose', dest='verbose', action='store_true', @@ -504,6 +506,22 @@ main.Append(CCFLAGS=['-fno-tree-vectorize']) if compareVersions(gcc_version, '4.6') >= 0: main.Append(CXXFLAGS=['-std=c++0x']) + # Determine the appropriate Link-Time Optimization (LTO) flags + if GetOption('lto'): + # Pass the LTO flag when compiling to produce GIMPLE + # output + main.Append(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.Append(LINKFLAGS = ['-flto=%d' % GetOption('num_jobs'), + '-fuse-linker-plugin']) + else: + print termcap.Yellow + termcap.Bold + \ + "Assuming you are running many batch jobs --lto increases "\ + "linking time, but improves runtime." + \ + termcap.Normal elif main['ICC']: pass #Fix me... add warning flags once we clean up icc warnings elif main['SUNCC']: diff -r 5f0321c03a26 -r faeddb9fb678 src/SConscript --- a/src/SConscript Mon Jul 02 08:21:53 2012 -0400 +++ b/src/SConscript Mon Jul 02 13:57:16 2012 +0100 @@ -933,31 +933,45 @@ new_env.M5Binary = targets[0] envList.append(new_env) -# Debug binary -ccflags = {} +# Create the ccflags and ldflags for the different targets and compilers +target_types = ['debug', 'opt', 'fast', 'prof'] + +# Start out with the compiler flags common to all compilers, +# i.e. they all use -g for opt and -g -pg for prof +ccflags = dict(zip(target_types, [[], ['-g'], [], ['-g', '-pg']])) + +# Start out with the linker flags common to all linkers, i.e. -pg for prof. +ldflags = dict(zip(target_types, [[], [], [], ['-pg']])) + +# For Link Time Optimization, the optimisation flags used to compile +# individual files are decoupled from those used at link time +# (i.e. you can compile with -O3 and perform LTO with -O0), so we need +# to also update the linker flags based on the target. if env['GCC']: if sys.platform == 'sunos5': - ccflags['debug'] = '-gstabs+' + ccflags['debug'] += ['-gstabs+'] else: - ccflags['debug'] = '-ggdb3' - ccflags['opt'] = '-g -O3' - ccflags['fast'] = '-O3' - ccflags['prof'] = '-O3 -g -pg' + ccflags['debug'] += ['-ggdb3'] + ldflags['debug'] += ['-O0'] + # opt, fast and prof all share the same cc and ld flags + for target in ['opt', 'fast', 'prof']: + ccflags[target] += ['-O3'] + ldflags[target] += ['-O3'] elif env['SUNCC']: - ccflags['debug'] = '-g0' - ccflags['opt'] = '-g -O' - ccflags['fast'] = '-fast' - ccflags['prof'] = '-fast -g -pg' + ccflags['debug'] += ['-g0'] + ccflags['opt'] += ['-O'] + ccflags['fast'] += ['-fast'] + ccflags['prof'] += ['-fast'] elif env['ICC']: - ccflags['debug'] = '-g -O0' - ccflags['opt'] = '-g -O' - ccflags['fast'] = '-fast' - ccflags['prof'] = '-fast -g -pg' + ccflags['debug'] += ['-g', '-O0'] + ccflags['opt'] += ['-O'] + ccflags['fast'] += ['-fast'] + ccflags['prof'] += ['-fast'] elif env['CLANG']: - ccflags['debug'] = '-g -O0' - ccflags['opt'] = '-g -O3' - ccflags['fast'] = '-O3' - ccflags['prof'] = '-O3 -g -pg' + ccflags['debug'] += ['-g', '-O0'] + ccflags['opt'] += ['-O3'] + ccflags['fast'] += ['-O3'] + ccflags['prof'] += ['-O3'] else: print 'Unknown compiler, please fix compiler options' Exit(1) @@ -967,8 +981,7 @@ # need. We try to identify the needed environment for each target; if # we can't, we fall back on instantiating all the environments just to # be safe. -target_types = ['debug', 'opt', 'fast', 'prof'] -obj2target = {'do': 'debug', 'o': 'opt', 'fo': 'fast', 'po': 'prof'} +obj2target = dict(zip(['do', 'o', 'fo', 'po'], target_types)) def identifyTarget(t): ext = t.split('.')[-1] @@ -989,25 +1002,28 @@ if 'debug' in needed_envs: makeEnv('debug', '.do', CCFLAGS = Split(ccflags['debug']), - CPPDEFINES = ['DEBUG', 'TRACING_ON=1']) + CPPDEFINES = ['DEBUG', 'TRACING_ON=1'], + LINKFLAGS = Split(ldflags['debug'])) # Optimized binary if 'opt' in needed_envs: makeEnv('opt', '.o', CCFLAGS = Split(ccflags['opt']), - CPPDEFINES = ['TRACING_ON=1']) + CPPDEFINES = ['TRACING_ON=1'], + LINKFLAGS = Split(ldflags['opt'])) # "Fast" binary if 'fast' in needed_envs: makeEnv('fast', '.fo', strip = True, CCFLAGS = Split(ccflags['fast']), - CPPDEFINES = ['NDEBUG', 'TRACING_ON=0']) + CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], + LINKFLAGS = Split(ldflags['fast'])) # Profiled binary if 'prof' in needed_envs: makeEnv('prof', '.po', CCFLAGS = Split(ccflags['prof']), CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'], - LINKFLAGS = '-pg') + LINKFLAGS = Split(ldflags['prof'])) Return('envList')