Index: llvm/include/llvm/LTO/Config.h =================================================================== --- llvm/include/llvm/LTO/Config.h +++ llvm/include/llvm/LTO/Config.h @@ -55,6 +55,7 @@ CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; CodeGenFileType CGFileType = CGFT_ObjectFile; unsigned OptLevel = 2; + unsigned SizeLevel = 0; bool DisableVerify = false; /// Use the new pass manager Index: llvm/lib/LTO/LTOBackend.cpp =================================================================== --- llvm/lib/LTO/LTOBackend.cpp +++ llvm/lib/LTO/LTOBackend.cpp @@ -311,7 +311,8 @@ PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple())); if (Conf.Freestanding) PMB.LibraryInfo->disableAllFunctions(); - PMB.Inliner = createFunctionInliningPass(); + PMB.Inliner = + createFunctionInliningPass(Conf.OptLevel, Conf.SizeLevel, false); PMB.ExportSummary = ExportSummary; PMB.ImportSummary = ImportSummary; // Unconditionally verify input since it is not verified before this Index: llvm/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/lib/LTO/LTOCodeGenerator.cpp +++ llvm/lib/LTO/LTOCodeGenerator.cpp @@ -185,6 +185,10 @@ } void LTOCodeGenerator::setOptLevel(unsigned Level) { + if (Level > 3) { + Config.SizeLevel = Level - 3; + Level = 2; + } Config.OptLevel = Level; Config.PTO.LoopVectorization = Config.OptLevel > 1; Config.PTO.SLPVectorization = Config.OptLevel > 1; Index: llvm/test/tools/lto/lto_optsize.ll =================================================================== --- /dev/null +++ llvm/test/tools/lto/lto_optsize.ll @@ -0,0 +1,51 @@ +; RUN: llvm-as %s -o %t.o + +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol inner -exported_symbol outer -exported_symbol outer2 -exported_symbol extern -exported_symbol a -mllvm -Os +; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=OS %s + +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol inner -exported_symbol outer -exported_symbol outer2 -exported_symbol extern -exported_symbol a -mllvm -Oz +; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=OZ %s + +; The inline threshold for a function with the optsize attribute is currently +; the same as the global inline threshold for -Os. Check that the optsize +; function attribute doesn't alter the function-specific inline threshold if the +; global inline threshold is lower (as for -Oz). + +target triple = "x86_64-apple-macosx10.8.0" + +@a = global i32 4 + +; This function should be larger than the inline threshold for -Oz (25), but +; smaller than the inline threshold for optsize (75). +define i32 @inner() { + call void @extern() + %a1 = load volatile i32, i32* @a + %x1 = add i32 %a1, %a1 + %a2 = load volatile i32, i32* @a + %x2 = add i32 %x1, %a2 + %a3 = load volatile i32, i32* @a + %x3 = add i32 %x2, %a3 + %a4 = load volatile i32, i32* @a + %x4 = add i32 %x3, %a4 + %a5 = load volatile i32, i32* @a + %x5 = add i32 %x3, %a5 + ret i32 %x5 +} + +; @inner() should be inlined for -Os but not for -Oz. +; OZ: call +; OS-NOT: call +define i32 @outer() optsize { + %r = call i32 @inner() + ret i32 %r +} + +; @inner() should not be inlined for -Os and -Oz. +; OZ: call +; OS: call +define i32 @outer2() minsize { + %r = call i32 @inner() + ret i32 %r +} + +declare void @extern() Index: llvm/tools/lto/lto.cpp =================================================================== --- llvm/tools/lto/lto.cpp +++ llvm/tools/lto/lto.cpp @@ -152,8 +152,13 @@ LTOCodeGenerator *CG = unwrap(cg); CG->setAttrs(codegen::getMAttrs()); - if (OptLevel < '0' || OptLevel > '3') - report_fatal_error("Optimization level must be between 0 and 3"); + if (OptLevel == 's') + OptLevel = '4'; + else if (OptLevel == 'z') + OptLevel = '5'; + if (OptLevel < '0' || OptLevel > '5') + report_fatal_error( + "Optimization level must be between 0 and 3 or Os or Oz"); CG->setOptLevel(OptLevel - '0'); CG->setFreestanding(EnableFreestanding); CG->setDisableVerify(DisableVerify); @@ -521,8 +526,13 @@ CodeGen->setFreestanding(EnableFreestanding); if (OptLevel.getNumOccurrences()) { - if (OptLevel < '0' || OptLevel > '3') - report_fatal_error("Optimization level must be between 0 and 3"); + if (OptLevel == 's') + OptLevel = '4'; + else if (OptLevel == 'z') + OptLevel = '5'; + if (OptLevel < '0' || OptLevel > '5') + report_fatal_error( + "Optimization level must be between 0 and 3 or Os or Oz"); CodeGen->setOptLevel(OptLevel - '0'); switch (OptLevel) { case '0':