From a63cde26ff698284ecdbec357966ca9d69e1d83a Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 15 Dec 2010 22:16:21 +0000 Subject: Teach machine cse to commute instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121903 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineCSE.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/MachineCSE.cpp') diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 0143d0f..fc3f594 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -24,7 +24,6 @@ #include "llvm/ADT/ScopedHashTable.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" using namespace llvm; @@ -33,6 +32,7 @@ STATISTIC(NumCoalesces, "Number of copies coalesced"); STATISTIC(NumCSEs, "Number of common subexpression eliminated"); STATISTIC(NumPhysCSEs, "Number of physreg referencing common subexpr eliminated"); +STATISTIC(NumCommutes, "Number of copies coalesced after commuting"); namespace { class MachineCSE : public MachineFunctionPass { @@ -368,7 +368,22 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) { FoundCSE = VNT.count(MI); } } - // FIXME: commute commutable instructions? + + // Commute commutable instructions. + bool Commuted = false; + if (!FoundCSE && MI->getDesc().isCommutable()) { + MachineInstr *NewMI = TII->commuteInstruction(MI); + if (NewMI) { + Commuted = true; + FoundCSE = VNT.count(NewMI); + if (NewMI != MI) + // New instruction. It doesn't need to be kept. + NewMI->eraseFromParent(); + else if (!FoundCSE) + // MI was changed but it didn't help, commute it back! + (void)TII->commuteInstruction(MI); + } + } // If the instruction defines physical registers and the values *may* be // used, then it's not safe to replace it with a common subexpression. @@ -430,6 +445,8 @@ bool MachineCSE::ProcessBlock(MachineBasicBlock *MBB) { ++NumCSEs; if (!PhysRefs.empty()) ++NumPhysCSEs; + if (Commuted) + ++NumCommutes; } else { DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n"); VNT.insert(MI, CurrVN++); -- cgit v1.1 From 53eeba586dac8a25db63fe02a00ef10feb8b3925 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Mon, 3 Jan 2011 04:07:46 +0000 Subject: Use a RecyclingAllocator to allocate values for MachineCSE's ScopedHashTable for a 28% speedup of MachineCSE time on 403.gcc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122735 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineCSE.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'lib/CodeGen/MachineCSE.cpp') diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index fc3f594..bb1db86 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/RecyclingAllocator.h" using namespace llvm; @@ -65,10 +66,13 @@ namespace { private: const unsigned LookAheadLimit; - typedef ScopedHashTableScope ScopeType; + typedef RecyclingAllocator > AllocatorTy; + typedef ScopedHashTable ScopedHTType; + typedef ScopedHTType::ScopeTy ScopeType; DenseMap ScopeMap; - ScopedHashTable VNT; + ScopedHTType VNT; SmallVector Exps; unsigned CurrVN; -- cgit v1.1 From c36b7069b42bece963b7e6adf020353ce990ef76 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 7 Jan 2011 23:50:32 +0000 Subject: Do not model all INLINEASM instructions as having unmodelled side effects. Instead encode llvm IR level property "HasSideEffects" in an operand (shared with IsAlignStack). Added MachineInstrs::hasUnmodeledSideEffects() to check the operand when the instruction is an INLINEASM. This allows memory instructions to be moved around INLINEASM instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123044 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineCSE.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/MachineCSE.cpp') diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index bb1db86..3e54784 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -262,7 +262,7 @@ bool MachineCSE::isCSECandidate(MachineInstr *MI) { // Ignore stuff that we obviously can't move. const TargetInstrDesc &TID = MI->getDesc(); if (TID.mayStore() || TID.isCall() || TID.isTerminator() || - TID.hasUnmodeledSideEffects()) + MI->hasUnmodeledSideEffects()) return false; if (TID.mayLoad()) { -- cgit v1.1 From c9df025e33ac435adb3b3318d237c36ca7cec659 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 10 Jan 2011 02:58:51 +0000 Subject: Simplify a bunch of isVirtualRegister() and isPhysicalRegister() logic. These functions not longer assert when passed 0, but simply return false instead. No functional change intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123155 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineCSE.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/CodeGen/MachineCSE.cpp') diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 3e54784..60ad46a 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -116,7 +116,7 @@ bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI, if (!MO.isReg() || !MO.isUse()) continue; unsigned Reg = MO.getReg(); - if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg)) + if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; if (!MRI->hasOneNonDBGUse(Reg)) // Only coalesce single use copies. This ensure the copy will be @@ -300,7 +300,7 @@ bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg, bool HasVRegUse = false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isUse() && MO.getReg() && + if (MO.isReg() && MO.isUse() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) { HasVRegUse = true; break; -- cgit v1.1 From 622a11bc0764897f6aaf80fe96b3abac6215f06b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 10 Jan 2011 07:51:31 +0000 Subject: fit in 80 cols and use MBB::isSuccessor instead of a hand rolled std::find. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123164 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineCSE.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib/CodeGen/MachineCSE.cpp') diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index 60ad46a..07a7d27 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -284,14 +284,13 @@ bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg, MachineInstr *CSMI, MachineInstr *MI) { // FIXME: Heuristics that works around the lack the live range splitting. - // Heuristics #1: Don't cse "cheap" computating if the def is not local or in an - // immediate predecessor. We don't want to increase register pressure and end up - // causing other computation to be spilled. + // Heuristics #1: Don't CSE "cheap" computation if the def is not local or in + // an immediate predecessor. We don't want to increase register pressure and + // end up causing other computation to be spilled. if (MI->getDesc().isAsCheapAsAMove()) { MachineBasicBlock *CSBB = CSMI->getParent(); MachineBasicBlock *BB = MI->getParent(); - if (CSBB != BB && - find(CSBB->succ_begin(), CSBB->succ_end(), BB) == CSBB->succ_end()) + if (CSBB != BB && !CSBB->isSuccessor(BB)) return false; } -- cgit v1.1