diff options
author | Quentin Colombet <qcolombet@apple.com> | 2017-06-05 23:51:27 +0000 |
---|---|---|
committer | Quentin Colombet <qcolombet@apple.com> | 2017-06-05 23:51:27 +0000 |
commit | c668935d85bc38f733e00315d419c7778852063a (patch) | |
tree | 007484bcabac1321f621650920f08178a1ae25d2 /llvm/lib | |
parent | a6fef0e5dbf938f8442e5adcd6b8c1b35db56d62 (diff) | |
download | bcm5719-llvm-c668935d85bc38f733e00315d419c7778852063a.tar.gz bcm5719-llvm-c668935d85bc38f733e00315d419c7778852063a.zip |
[InlineSpiller] Don't spill fully undef values
Althought it is not wrong to spill undef values, it is useless and harms
both code size and runtime. Before spilling a value, check that its
content actually matters.
http://www.llvm.org/PR33311
llvm-svn: 304752
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/InlineSpiller.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp index b7ab404070b..68f2a2ed9a1 100644 --- a/llvm/lib/CodeGen/InlineSpiller.cpp +++ b/llvm/lib/CodeGen/InlineSpiller.cpp @@ -857,14 +857,36 @@ void InlineSpiller::insertReload(unsigned NewVReg, ++NumReloads; } +/// Check if \p Def fully defines a VReg with an undefined value. +/// If that's the case, that means the value of VReg is actually +/// not relevant. +static bool isFullUndefDef(const MachineInstr &Def) { + if (!Def.isImplicitDef()) + return false; + assert(Def.getNumOperands() == 1 && + "Implicit def with more than one definition"); + // We can say that the VReg defined by Def is undef, only if it is + // fully defined by Def. Otherwise, some of the lanes may not be + // undef and the value of the VReg matters. + return !Def.getOperand(0).getSubReg(); +} + /// insertSpill - Insert a spill of NewVReg after MI. void InlineSpiller::insertSpill(unsigned NewVReg, bool isKill, MachineBasicBlock::iterator MI) { MachineBasicBlock &MBB = *MI->getParent(); MachineInstrSpan MIS(MI); - TII.storeRegToStackSlot(MBB, std::next(MI), NewVReg, isKill, StackSlot, - MRI.getRegClass(NewVReg), &TRI); + if (isFullUndefDef(*MI)) + // Don't spill undef value. + // Anything works for undef, in particular keeping the memory + // uninitialized is a viable option and it saves code size and + // run time. + BuildMI(MBB, std::next(MI), MI->getDebugLoc(), TII.get(TargetOpcode::KILL)) + .addReg(NewVReg, getKillRegState(isKill)); + else + TII.storeRegToStackSlot(MBB, std::next(MI), NewVReg, isKill, StackSlot, + MRI.getRegClass(NewVReg), &TRI); LIS.InsertMachineInstrRangeInMaps(std::next(MI), MIS.end()); |