diff options
Diffstat (limited to 'lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp')
-rw-r--r-- | lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp b/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp index 2503764..2cf3c22 100644 --- a/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp +++ b/lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp @@ -38,8 +38,8 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/RegisterClassInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -96,6 +96,10 @@ static bool isMla(MachineInstr *MI) { } } +namespace llvm { +static void initializeAArch64A57FPLoadBalancingPass(PassRegistry &); +} + //===----------------------------------------------------------------------===// namespace { @@ -109,14 +113,15 @@ static const char *ColorNames[2] = { "Even", "Odd" }; class Chain; class AArch64A57FPLoadBalancing : public MachineFunctionPass { - const AArch64InstrInfo *TII; MachineRegisterInfo *MRI; const TargetRegisterInfo *TRI; RegisterClassInfo RCI; public: static char ID; - explicit AArch64A57FPLoadBalancing() : MachineFunctionPass(ID) {} + explicit AArch64A57FPLoadBalancing() : MachineFunctionPass(ID) { + initializeAArch64A57FPLoadBalancingPass(*PassRegistry::getPassRegistry()); + } bool runOnMachineFunction(MachineFunction &F) override; @@ -143,8 +148,16 @@ private: Color getColor(unsigned Register); Chain *getAndEraseNext(Color PreferredColor, std::vector<Chain*> &L); }; +} + char AArch64A57FPLoadBalancing::ID = 0; +INITIALIZE_PASS_BEGIN(AArch64A57FPLoadBalancing, DEBUG_TYPE, + "AArch64 A57 FP Load-Balancing", false, false) +INITIALIZE_PASS_END(AArch64A57FPLoadBalancing, DEBUG_TYPE, + "AArch64 A57 FP Load-Balancing", false, false) + +namespace { /// A Chain is a sequence of instructions that are linked together by /// an accumulation operand. For example: /// @@ -259,7 +272,7 @@ public: } /// Return true if this chain starts before Other. - bool startsBefore(Chain *Other) { + bool startsBefore(const Chain *Other) const { return StartInstIdx < Other->StartInstIdx; } @@ -297,10 +310,8 @@ bool AArch64A57FPLoadBalancing::runOnMachineFunction(MachineFunction &F) { bool Changed = false; DEBUG(dbgs() << "***** AArch64A57FPLoadBalancing *****\n"); - const TargetMachine &TM = F.getTarget(); MRI = &F.getRegInfo(); TRI = F.getRegInfo().getTargetRegisterInfo(); - TII = TM.getSubtarget<AArch64Subtarget>().getInstrInfo(); RCI.runOnMachineFunction(F); for (auto &MBB : F) { @@ -431,10 +442,17 @@ bool AArch64A57FPLoadBalancing::colorChainSet(std::vector<Chain*> GV, // chains that we cannot change before we look at those we can, // so the parity counter is updated and we know what color we should // change them to! + // Final tie-break with instruction order so pass output is stable (i.e. not + // dependent on malloc'd pointer values). std::sort(GV.begin(), GV.end(), [](const Chain *G1, const Chain *G2) { if (G1->size() != G2->size()) return G1->size() > G2->size(); - return G1->requiresFixup() > G2->requiresFixup(); + if (G1->requiresFixup() != G2->requiresFixup()) + return G1->requiresFixup() > G2->requiresFixup(); + // Make sure startsBefore() produces a stable final order. + assert((G1 == G2 || (G1->startsBefore(G2) ^ G2->startsBefore(G1))) && + "Starts before not total order!"); + return G1->startsBefore(G2); }); Color PreferredColor = Parity < 0 ? Color::Even : Color::Odd; @@ -481,10 +499,16 @@ int AArch64A57FPLoadBalancing::scavengeRegister(Chain *G, Color C, RS.forward(I); AvailableRegs &= RS.getRegsAvailable(TRI->getRegClass(RegClassID)); - // Remove any registers clobbered by a regmask. + // Remove any registers clobbered by a regmask or any def register that is + // immediately dead. for (auto J : I->operands()) { if (J.isRegMask()) AvailableRegs.clearBitsNotInMask(J.getRegMask()); + + if (J.isReg() && J.isDef() && AvailableRegs[J.getReg()]) { + assert(J.isDead() && "Non-dead def should have been removed by now!"); + AvailableRegs.reset(J.getReg()); + } } } |