Index: llvm/trunk/docs/LangRef.rst =================================================================== --- llvm/trunk/docs/LangRef.rst +++ llvm/trunk/docs/LangRef.rst @@ -1289,9 +1289,9 @@ that are recognized by LLVM to handle asynchronous exceptions, such as SEH, will still provide their implementation defined semantics. ``optnone`` - This function attribute indicates that the function is not optimized - by any optimization or code generator passes with the - exception of interprocedural optimization passes. + This function attribute indicates that most optimization passes will skip + this function, with the exception of interprocedural optimization passes. + Code generation defaults to the "fast" instruction selector. This attribute cannot be used together with the ``alwaysinline`` attribute; this attribute is also incompatible with the ``minsize`` attribute and the ``optsize`` attribute. Index: llvm/trunk/include/llvm/Target/TargetMachine.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetMachine.h +++ llvm/trunk/include/llvm/Target/TargetMachine.h @@ -102,6 +102,7 @@ const MCSubtargetInfo *STI; unsigned RequireStructuredCFG : 1; + unsigned O0WantsFastISel : 1; /// This API is here to support the C API, deprecated in 3.7 release. /// This should never be used outside of legacy existing client. @@ -190,6 +191,8 @@ void setOptLevel(CodeGenOpt::Level Level) const; void setFastISel(bool Enable) { Options.EnableFastISel = Enable; } + bool getO0WantsFastISel() { return O0WantsFastISel; } + void setO0WantsFastISel(bool Enable) { O0WantsFastISel = Enable; } bool shouldPrintMachineCode() const { return Options.PrintMachineCode; } Index: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp =================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp @@ -125,9 +125,10 @@ PM.add(new MachineFunctionAnalysis(*TM, MFInitializer)); // Enable FastISel with -fast, but allow that to be overridden. + TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE); if (EnableFastISelOption == cl::BOU_TRUE || (TM->getOptLevel() == CodeGenOpt::None && - EnableFastISelOption != cl::BOU_FALSE)) + TM->getO0WantsFastISel())) TM->setFastISel(true); // Ask the target for an isel. Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -264,13 +264,17 @@ return; IS.OptLevel = NewOptLevel; IS.TM.setOptLevel(NewOptLevel); - SavedFastISel = IS.TM.Options.EnableFastISel; - if (NewOptLevel == CodeGenOpt::None) - IS.TM.setFastISel(true); DEBUG(dbgs() << "\nChanging optimization level for Function " << IS.MF->getFunction()->getName() << "\n"); DEBUG(dbgs() << "\tBefore: -O" << SavedOptLevel << " ; After: -O" << NewOptLevel << "\n"); + SavedFastISel = IS.TM.Options.EnableFastISel; + if (NewOptLevel == CodeGenOpt::None) { + IS.TM.setFastISel(IS.TM.getO0WantsFastISel()); + DEBUG(dbgs() << "\tFastISel is " + << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled") + << "\n"); + } } ~OptLevelChanger() { Index: llvm/trunk/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll +++ llvm/trunk/test/CodeGen/Mips/emergency-spill-slot-near-fp.ll @@ -1,5 +1,5 @@ ; Check that register scavenging spill slot is close to $fp. -; RUN: llc -march=mipsel -O0 -fast-isel=false < %s | FileCheck %s +; RUN: llc -march=mipsel -O0 < %s | FileCheck %s ; CHECK: sw ${{.*}}, 8($sp) ; CHECK: lw ${{.*}}, 8($sp) @@ -31,4 +31,4 @@ ret i32 0 } -attributes #0 = { noinline optnone "no-frame-pointer-elim"="true" } +attributes #0 = { noinline "no-frame-pointer-elim"="true" } Index: llvm/trunk/test/Feature/optnone-llc.ll =================================================================== --- llvm/trunk/test/Feature/optnone-llc.ll +++ llvm/trunk/test/Feature/optnone-llc.ll @@ -3,11 +3,13 @@ ; RUN: llc -O2 -debug %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=LLC-Ox ; RUN: llc -O3 -debug %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=LLC-Ox ; RUN: llc -misched-postra -debug %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=LLC-MORE +; RUN: llc -O1 -debug-only=isel %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=FAST +; RUN: llc -O1 -debug-only=isel -fast-isel=false %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOFAST ; REQUIRES: asserts, default_triple ; This test verifies that we don't run Machine Function optimizations -; on optnone functions. +; on optnone functions, and that we can turn off FastISel. ; Function Attrs: noinline optnone define i32 @_Z3fooi(i32 %x) #0 { @@ -52,3 +54,7 @@ ; Alternate post-RA scheduler. ; LLC-MORE: Skipping pass 'PostRA Machine Instruction Scheduler' + +; Selectively disable FastISel for optnone functions. +; FAST: FastISel is enabled +; NOFAST: FastISel is disabled