aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-01-12 00:09:37 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-01-12 00:09:37 +0000
commita5a81d70720a4ce6ac7538927c2a874b0dfa8bd2 (patch)
treea97a5454dfbd99f0a45929908becf7cc692b74af
parent77beb479f556093c5f1b4854fcbb095cda34f202 (diff)
downloadexternal_llvm-a5a81d70720a4ce6ac7538927c2a874b0dfa8bd2.zip
external_llvm-a5a81d70720a4ce6ac7538927c2a874b0dfa8bd2.tar.gz
external_llvm-a5a81d70720a4ce6ac7538927c2a874b0dfa8bd2.tar.bz2
Add TargetInstrInfo::isCoalescableInstr. It returns true if the specified
instruction is copy like where the source and destination registers can overlap. This is to be used by the coalescable to coalesce the source and destination registers of instructions like X86::MOVSX64rr32. Apparently some crazy people believe the coalescer is too simple. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93210 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetInstrInfo.h13
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp53
-rw-r--r--lib/Target/X86/X86InstrInfo.h8
3 files changed, 74 insertions, 0 deletions
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index c57a2d4..6172fcf 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -149,6 +149,19 @@ public:
return false;
}
+ /// isCoalescableInstr - Return true if the instruction is "coalescable". That
+ /// is, it's like a copy where it's legal for the source to overlap the
+ /// destination. e.g. X86::MOVSX64rr32.
+ virtual bool isCoalescableInstr(const MachineInstr &MI, bool &isCopy,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
+ if (isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
+ isCopy = true;
+ return true;
+ }
+ return false;
+ }
+
/// isIdentityCopy - Return true if the instruction is a copy (or
/// extract_subreg, insert_subreg, subreg_to_reg) where the source and
/// destination registers are the same.
diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp
index 9600cff..52077cf 100644
--- a/lib/Target/X86/X86InstrInfo.cpp
+++ b/lib/Target/X86/X86InstrInfo.cpp
@@ -712,6 +712,59 @@ bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
}
}
+bool
+X86InstrInfo::isCoalescableInstr(const MachineInstr &MI, bool &isCopy,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
+ switch (MI.getOpcode()) {
+ default: break;
+ case X86::MOVSX16rr8:
+ case X86::MOVZX16rr8:
+ case X86::MOVSX32rr8:
+ case X86::MOVZX32rr8:
+ case X86::MOVSX64rr8:
+ case X86::MOVZX64rr8:
+ case X86::MOVSX32rr16:
+ case X86::MOVZX32rr16:
+ case X86::MOVSX64rr16:
+ case X86::MOVZX64rr16:
+ case X86::MOVSX64rr32:
+ case X86::MOVZX64rr32: {
+ if (MI.getOperand(0).getSubReg() || MI.getOperand(1).getSubReg())
+ // Be conservative.
+ return false;
+ isCopy = false;
+ SrcReg = MI.getOperand(1).getReg();
+ DstReg = MI.getOperand(0).getReg();
+ DstSubIdx = 0;
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable(0);
+ break;
+ case X86::MOVSX16rr8:
+ case X86::MOVZX16rr8:
+ case X86::MOVSX32rr8:
+ case X86::MOVZX32rr8:
+ case X86::MOVSX64rr8:
+ case X86::MOVZX64rr8:
+ SrcSubIdx = 1;
+ break;
+ case X86::MOVSX32rr16:
+ case X86::MOVZX32rr16:
+ case X86::MOVSX64rr16:
+ case X86::MOVZX64rr16:
+ SrcSubIdx = 3;
+ break;
+ case X86::MOVSX64rr32:
+ case X86::MOVZX64rr32:
+ SrcSubIdx = 4;
+ break;
+ }
+ }
+ }
+ return isMoveInstr(MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
+}
+
/// isFrameOperand - Return true and the FrameIndex if the specified
/// operand and follow operands form a reference to the stack frame.
bool X86InstrInfo::isFrameOperand(const MachineInstr *MI, unsigned int Op,
diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h
index b83441d..6ae7808 100644
--- a/lib/Target/X86/X86InstrInfo.h
+++ b/lib/Target/X86/X86InstrInfo.h
@@ -448,6 +448,14 @@ public:
unsigned &SrcReg, unsigned &DstReg,
unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+ /// isCoalescableInstr - Return true if the instruction is "coalescable". That
+ /// is, it's like a copy where it's legal for the source to overlap the
+ /// destination. e.g. X86::MOVSX64rr32.
+ virtual bool isCoalescableInstr(const MachineInstr &MI, bool &isCopy,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+
+
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
/// isLoadFromStackSlotPostFE - Check for post-frame ptr elimination
/// stack locations as well. This uses a heuristic so it isn't