summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2013-10-14 22:19:03 +0000
committerAndrew Trick <atrick@apple.com>2013-10-14 22:19:03 +0000
commita6a9ac5aa1092067e6e1546226d8bdd6a4bfcf99 (patch)
treed28e7ac2e1333f9dc7af9c1f71719d94cba35483 /include
parent966772931eea7cdc3cdd7199e304d667aa344bd7 (diff)
downloadllvm-a6a9ac5aa1092067e6e1546226d8bdd6a4bfcf99.tar.gz
llvm-a6a9ac5aa1092067e6e1546226d8bdd6a4bfcf99.tar.bz2
llvm-a6a9ac5aa1092067e6e1546226d8bdd6a4bfcf99.tar.xz
Fix the ExecutionDepsFix pass to handle AVX instructions.
This pass is needed to break false dependencies. Without it, unlucky register assignment can result in wild (5x) swings in performance. This pass was trying to handle AVX but not getting it right. AVX doesn't have partial register defs, it has unused register reads in which the high bits of a source operand are copied into the unused bits of the dest. Fixing this requires conservative liveness analysis. This is awkard because the pass already has its own pseudo-liveness. However, proper liveness is expensive, and we would like to use a generic utility to compute it. The fix only invokes liveness on-demand. It is rare to detect a case that needs undef-read dependence breaking, but when it happens, it can be needed many times within a very large block. I think the existing heuristic which uses a register window of 16 is too conservative for loop-carried false dependencies. If the loop is a reduction. The out-of-order engine may be able to execute several loop iterations in parallel. However, I'll leave this tuning exercise for next time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192635 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Target/TargetInstrInfo.h20
1 files changed, 20 insertions, 0 deletions
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index b8599daf3f..f9edc7d8df 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -942,6 +942,26 @@ public:
return 0;
}
+ /// \brief Return the minimum clearance before an instruction that reads an
+ /// unused register.
+ ///
+ /// For example, AVX instructions may copy part of an register operand into
+ /// the unused high bits of the destination register.
+ ///
+ /// vcvtsi2sdq %rax, %xmm0<undef>, %xmm14
+ ///
+ /// In the code above, vcvtsi2sdq copies %xmm0[127:64] into %xmm14 creating a
+ /// false dependence on any previous write to %xmm0.
+ ///
+ /// This hook works similarly to getPartialRegUpdateClearance, except that it
+ /// does not take an operand index. Instead sets \p OpNum to the index of the
+ /// unused register.
+ virtual unsigned getUndefRegClearance(const MachineInstr *MI, unsigned &OpNum,
+ const TargetRegisterInfo *TRI) const {
+ // The default implementation returns 0 for no undef register dependency.
+ return 0;
+ }
+
/// breakPartialRegDependency - Insert a dependency-breaking instruction
/// before MI to eliminate an unwanted dependency on OpNum.
///