aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManman Ren <mren@apple.com>2012-08-07 06:16:46 +0000
committerManman Ren <mren@apple.com>2012-08-07 06:16:46 +0000
commitba86b13ad9cd6a9707a954598863da1e2a9f773b (patch)
tree482ffd2aed786cddf7cce28e96075c7915155911
parentcbfce4557751acef4e7970d6e4b9583ced7e0e93 (diff)
downloadexternal_llvm-ba86b13ad9cd6a9707a954598863da1e2a9f773b.zip
external_llvm-ba86b13ad9cd6a9707a954598863da1e2a9f773b.tar.gz
external_llvm-ba86b13ad9cd6a9707a954598863da1e2a9f773b.tar.bz2
MachineCSE: Update the heuristics for isProfitableToCSE.
If the result of a common subexpression is used at all uses of the candidate expression, CSE should not increase the live range of the common subexpression. rdar://11393714 and rdar://11819721 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161396 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/MachineCSE.cpp23
-rw-r--r--test/CodeGen/X86/block-placement.ll2
-rw-r--r--test/CodeGen/X86/machine-cse.ll35
3 files changed, 59 insertions, 1 deletions
diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp
index 9cfe9ab..0a76f8d 100644
--- a/lib/CodeGen/MachineCSE.cpp
+++ b/lib/CodeGen/MachineCSE.cpp
@@ -324,6 +324,29 @@ bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg,
MachineInstr *CSMI, MachineInstr *MI) {
// FIXME: Heuristics that works around the lack the live range splitting.
+ // If CSReg is used at all uses of Reg, CSE should not increase register
+ // pressure of CSReg.
+ bool MayIncreasePressure = true;
+ if (TargetRegisterInfo::isVirtualRegister(CSReg) &&
+ TargetRegisterInfo::isVirtualRegister(Reg)) {
+ MayIncreasePressure = false;
+ SmallPtrSet<MachineInstr*, 8> CSUses;
+ for (MachineRegisterInfo::use_nodbg_iterator I =MRI->use_nodbg_begin(CSReg),
+ E = MRI->use_nodbg_end(); I != E; ++I) {
+ MachineInstr *Use = &*I;
+ CSUses.insert(Use);
+ }
+ for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg),
+ E = MRI->use_nodbg_end(); I != E; ++I) {
+ MachineInstr *Use = &*I;
+ if (!CSUses.count(Use)) {
+ MayIncreasePressure = true;
+ break;
+ }
+ }
+ }
+ if (!MayIncreasePressure) return true;
+
// 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.
diff --git a/test/CodeGen/X86/block-placement.ll b/test/CodeGen/X86/block-placement.ll
index fc7b638..ab23b88 100644
--- a/test/CodeGen/X86/block-placement.ll
+++ b/test/CodeGen/X86/block-placement.ll
@@ -634,7 +634,7 @@ define void @test_unnatural_cfg_backwards_inner_loop() {
;
; CHECK: test_unnatural_cfg_backwards_inner_loop
; CHECK: %entry
-; CHECK: %body
+; CHECK: [[BODY:# BB#[0-9]+]]:
; CHECK: %loop2b
; CHECK: %loop1
; CHECK: %loop2a
diff --git a/test/CodeGen/X86/machine-cse.ll b/test/CodeGen/X86/machine-cse.ll
index a757cde..33bef70 100644
--- a/test/CodeGen/X86/machine-cse.ll
+++ b/test/CodeGen/X86/machine-cse.ll
@@ -99,3 +99,38 @@ return: ; preds = %if.end, %entry
%retval.0 = phi i32 [ 1, %entry ], [ %., %if.end ]
ret i32 %retval.0
}
+
+; rdar://11393714
+define i8* @bsd_memchr(i8* %s, i32 %a, i32 %c, i64 %n) nounwind ssp {
+; CHECK: %entry
+; CHECK: xorl
+; CHECK: %preheader
+; CHECK: %do.body
+; CHECK-NOT: xorl
+; CHECK: %do.cond
+; CHECK-NOT: xorl
+; CHECK: %return
+entry:
+ %cmp = icmp eq i64 %n, 0
+ br i1 %cmp, label %return, label %preheader
+
+preheader:
+ %conv2 = and i32 %c, 255
+ br label %do.body
+
+do.body:
+ %n.addr.0 = phi i64 [ %dec, %do.cond ], [ %n, %preheader ]
+ %p.0 = phi i8* [ %incdec.ptr, %do.cond ], [ %s, %preheader ]
+ %cmp3 = icmp eq i32 %a, %conv2
+ br i1 %cmp3, label %return, label %do.cond
+
+do.cond:
+ %incdec.ptr = getelementptr inbounds i8* %p.0, i64 1
+ %dec = add i64 %n.addr.0, -1
+ %cmp6 = icmp eq i64 %dec, 0
+ br i1 %cmp6, label %return, label %do.body
+
+return:
+ %retval.0 = phi i8* [ null, %entry ], [ null, %do.cond ], [ %p.0, %do.body ]
+ ret i8* %retval.0
+}