mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Teach ISel not to optimize 'optnone' functions.
Based on work by Andrea Di Biagio. llvm-svn: 195317
This commit is contained in:
parent
682d6cc95b
commit
eba6ab82dd
@ -42,6 +42,9 @@ namespace llvm {
|
|||||||
CodeModel::Model getCodeModel() const { return CMModel; }
|
CodeModel::Model getCodeModel() const { return CMModel; }
|
||||||
|
|
||||||
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
|
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
|
||||||
|
|
||||||
|
// Allow overriding OptLevel on a per-function basis.
|
||||||
|
void setOptLevel(CodeGenOpt::Level Level) { OptLevel = Level; }
|
||||||
};
|
};
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
|
@ -75,7 +75,8 @@ protected: // Can only create subclasses.
|
|||||||
std::string TargetFS;
|
std::string TargetFS;
|
||||||
|
|
||||||
/// CodeGenInfo - Low level target information such as relocation model.
|
/// CodeGenInfo - Low level target information such as relocation model.
|
||||||
const MCCodeGenInfo *CodeGenInfo;
|
/// Non-const to allow resetting optimization level per-function.
|
||||||
|
MCCodeGenInfo *CodeGenInfo;
|
||||||
|
|
||||||
/// AsmInfo - Contains target specific asm information.
|
/// AsmInfo - Contains target specific asm information.
|
||||||
///
|
///
|
||||||
@ -213,6 +214,9 @@ public:
|
|||||||
/// Default, or Aggressive.
|
/// Default, or Aggressive.
|
||||||
CodeGenOpt::Level getOptLevel() const;
|
CodeGenOpt::Level getOptLevel() const;
|
||||||
|
|
||||||
|
/// \brief Overrides the optimization level.
|
||||||
|
void setOptLevel(CodeGenOpt::Level Level) const;
|
||||||
|
|
||||||
void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
|
void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
|
||||||
|
|
||||||
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
|
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
|
||||||
|
@ -222,6 +222,39 @@ defaultListDAGScheduler("default", "Best scheduler for the target",
|
|||||||
createDefaultScheduler);
|
createDefaultScheduler);
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
//===--------------------------------------------------------------------===//
|
||||||
|
/// \brief This struct is used by SelectionDAGISel to temporarily override
|
||||||
|
/// the optimization level on a per-function basis.
|
||||||
|
class OptLevelChanger {
|
||||||
|
SelectionDAGISel &IS;
|
||||||
|
CodeGenOpt::Level SavedOptLevel;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OptLevelChanger(SelectionDAGISel &ISel,
|
||||||
|
CodeGenOpt::Level NewOptLevel) : IS(ISel) {
|
||||||
|
SavedOptLevel = IS.OptLevel;
|
||||||
|
if (NewOptLevel == SavedOptLevel)
|
||||||
|
return;
|
||||||
|
IS.OptLevel = NewOptLevel;
|
||||||
|
IS.TM.setOptLevel(NewOptLevel);
|
||||||
|
DEBUG(dbgs() << "\nChanging optimization level for Function "
|
||||||
|
<< IS.MF->getFunction()->getName() << "\n");
|
||||||
|
DEBUG(dbgs() << "\tBefore: -O" << SavedOptLevel
|
||||||
|
<< " ; After: -O" << NewOptLevel << "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
~OptLevelChanger() {
|
||||||
|
if (IS.OptLevel == SavedOptLevel)
|
||||||
|
return;
|
||||||
|
DEBUG(dbgs() << "\nRestoring optimization level for Function "
|
||||||
|
<< IS.MF->getFunction()->getName() << "\n");
|
||||||
|
DEBUG(dbgs() << "\tBefore: -O" << IS.OptLevel
|
||||||
|
<< " ; After: -O" << SavedOptLevel << "\n");
|
||||||
|
IS.OptLevel = SavedOptLevel;
|
||||||
|
IS.TM.setOptLevel(SavedOptLevel);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
/// createDefaultScheduler - This creates an instruction scheduler appropriate
|
/// createDefaultScheduler - This creates an instruction scheduler appropriate
|
||||||
/// for the target.
|
/// for the target.
|
||||||
@ -370,6 +403,12 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
ST.resetSubtargetFeatures(MF);
|
ST.resetSubtargetFeatures(MF);
|
||||||
TM.resetTargetOptions(MF);
|
TM.resetTargetOptions(MF);
|
||||||
|
|
||||||
|
// Reset OptLevel to None for optnone functions.
|
||||||
|
CodeGenOpt::Level NewOptLevel = OptLevel;
|
||||||
|
if (Fn.hasFnAttribute(Attribute::OptimizeNone))
|
||||||
|
NewOptLevel = CodeGenOpt::None;
|
||||||
|
OptLevelChanger OLC(*this, NewOptLevel);
|
||||||
|
|
||||||
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
|
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
|
||||||
|
|
||||||
SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);
|
SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);
|
||||||
@ -948,7 +987,7 @@ static void collectFailStats(const Instruction *I) {
|
|||||||
void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
|
||||||
// Initialize the Fast-ISel state, if needed.
|
// Initialize the Fast-ISel state, if needed.
|
||||||
FastISel *FastIS = 0;
|
FastISel *FastIS = 0;
|
||||||
if (TM.Options.EnableFastISel)
|
if (TM.Options.EnableFastISel || Fn.hasFnAttribute(Attribute::OptimizeNone))
|
||||||
FastIS = getTargetLowering()->createFastISel(*FuncInfo, LibInfo);
|
FastIS = getTargetLowering()->createFastISel(*FuncInfo, LibInfo);
|
||||||
|
|
||||||
// Iterate over all basic blocks in the function.
|
// Iterate over all basic blocks in the function.
|
||||||
|
@ -164,6 +164,11 @@ CodeGenOpt::Level TargetMachine::getOptLevel() const {
|
|||||||
return CodeGenInfo->getOptLevel();
|
return CodeGenInfo->getOptLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TargetMachine::setOptLevel(CodeGenOpt::Level Level) const {
|
||||||
|
if (CodeGenInfo)
|
||||||
|
CodeGenInfo->setOptLevel(Level);
|
||||||
|
}
|
||||||
|
|
||||||
bool TargetMachine::getAsmVerbosityDefault() {
|
bool TargetMachine::getAsmVerbosityDefault() {
|
||||||
return AsmVerbosityDefault;
|
return AsmVerbosityDefault;
|
||||||
}
|
}
|
||||||
|
31
test/CodeGen/Generic/isel-optnone.ll
Normal file
31
test/CodeGen/Generic/isel-optnone.ll
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
; RUN: llc -debug < %s -o /dev/null 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
; Verify that the backend correctly overrides the optimization level
|
||||||
|
; of optnone functions during instruction selection.
|
||||||
|
|
||||||
|
define float @foo(float %x) #0 {
|
||||||
|
entry:
|
||||||
|
%add = fadd fast float %x, %x
|
||||||
|
%add1 = fadd fast float %add, %x
|
||||||
|
ret float %add1
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-NOT: Changing optimization level for Function foo
|
||||||
|
; CHECK-NOT: Restoring optimization level for Function foo
|
||||||
|
|
||||||
|
; Function Attrs: noinline optnone
|
||||||
|
define float @fooWithOptnone(float %x) #1 {
|
||||||
|
entry:
|
||||||
|
%add = fadd fast float %x, %x
|
||||||
|
%add1 = fadd fast float %add, %x
|
||||||
|
ret float %add1
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK: Changing optimization level for Function fooWithOptnone
|
||||||
|
; CHECK-NEXT: Before: -O2 ; After: -O0
|
||||||
|
|
||||||
|
; CHECK: Restoring optimization level for Function fooWithOptnone
|
||||||
|
; CHECK-NEXT: Before: -O0 ; After: -O2
|
||||||
|
|
||||||
|
attributes #0 = { "unsafe-fp-math"="true" }
|
||||||
|
attributes #1 = { noinline optnone "unsafe-fp-math"="true" }
|
Loading…
Reference in New Issue
Block a user