summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/ExecutionDepsFix.cpp
diff options
context:
space:
mode:
authorMarina Yatsina <marina.yatsina@intel.com>2016-08-11 07:32:08 +0000
committerMarina Yatsina <marina.yatsina@intel.com>2016-08-11 07:32:08 +0000
commit88f0c31f13d6ad02dc6a5e2d1f37dd57b7e6b260 (patch)
treef404da59828a8ce3a2a3570b405f1b3c48270241 /llvm/lib/CodeGen/ExecutionDepsFix.cpp
parentb83e73bceb64590f0879a2ed03aa3803bea7daf8 (diff)
downloadbcm5719-llvm-88f0c31f13d6ad02dc6a5e2d1f37dd57b7e6b260.tar.gz
bcm5719-llvm-88f0c31f13d6ad02dc6a5e2d1f37dd57b7e6b260.zip
Avoid false dependencies of undef machine operands
This patch helps avoid false dependencies on undef registers by updating the machine instructions' undef operand to use a register that the instruction is truly dependent on, or use a register with clearance higher than Pref. Pseudo example: loop: xmm0 = ... xmm1 = vcvtsi2sdl eax, xmm0<undef> ... = inst xmm0 jmp loop In this example, selecting xmm0 as the undef register creates false dependency between loop iterations. This false dependency cannot be solved by inserting an xor before vcvtsi2sdl because xmm0 is alive at the point of the vcvtsi2sdl instruction. Selecting a different register instead of xmm0, especially a register that is not used in the loop, will eliminate this problem. Differential Revision: https://reviews.llvm.org/D22466 llvm-svn: 278321
Diffstat (limited to 'llvm/lib/CodeGen/ExecutionDepsFix.cpp')
-rw-r--r--llvm/lib/CodeGen/ExecutionDepsFix.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/ExecutionDepsFix.cpp b/llvm/lib/CodeGen/ExecutionDepsFix.cpp
index 1fe5f459b69..5f91db9251c 100644
--- a/llvm/lib/CodeGen/ExecutionDepsFix.cpp
+++ b/llvm/lib/CodeGen/ExecutionDepsFix.cpp
@@ -203,6 +203,8 @@ private:
void processDefs(MachineInstr*, bool Kill);
void visitSoftInstr(MachineInstr*, unsigned mask);
void visitHardInstr(MachineInstr*, unsigned domain);
+ void pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
+ unsigned Pref);
bool shouldBreakDependence(MachineInstr*, unsigned OpIdx, unsigned Pref);
void processUndefReads(MachineBasicBlock*);
};
@@ -473,6 +475,56 @@ void ExeDepsFix::visitInstr(MachineInstr *MI) {
processDefs(MI, !DomP.first);
}
+/// \brief Helps avoid false dependencies on undef registers by updating the
+/// machine instructions' undef operand to use a register that the instruction
+/// is truly dependent on, or use a register with clearance higher than Pref.
+void ExeDepsFix::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
+ unsigned Pref) {
+ MachineOperand &MO = MI->getOperand(OpIdx);
+ assert(MO.isUndef() && "Expected undef machine operand");
+
+ unsigned OriginalReg = MO.getReg();
+
+ // Update only undef operands that are mapped to one register.
+ if (AliasMap[OriginalReg].size() != 1)
+ return;
+
+ // Get the undef operand's register class
+ const TargetRegisterClass *OpRC =
+ TII->getRegClass(MI->getDesc(), OpIdx, TRI, *MF);
+
+ // If the instruction has a true dependency, we can hide the false depdency
+ // behind it.
+ for (MachineOperand &CurrMO : MI->operands()) {
+ if (!CurrMO.isReg() || CurrMO.isDef() || CurrMO.isUndef() ||
+ !OpRC->contains(CurrMO.getReg()))
+ continue;
+ // We found a true dependency - replace the undef register with the true
+ // dependency.
+ MO.setReg(CurrMO.getReg());
+ return;
+ }
+
+ // Go over all registers in the register class and find the register with
+ // max clearance or clearance higher than Pref.
+ unsigned MaxClearance = 0;
+ unsigned MaxClearanceReg = OriginalReg;
+ for (unsigned rx = 0; rx < OpRC->getNumRegs(); ++rx) {
+ unsigned Clearance = CurInstr - LiveRegs[rx].Def;
+ if (Clearance <= MaxClearance)
+ continue;
+ MaxClearance = Clearance;
+ MaxClearanceReg = OpRC->getRegister(rx);
+
+ if (MaxClearance > Pref)
+ break;
+ }
+
+ // Update the operand if we found a register with better clearance.
+ if (MaxClearanceReg != OriginalReg)
+ MO.setReg(MaxClearanceReg);
+}
+
/// \brief Return true to if it makes sense to break dependence on a partial def
/// or undef use.
bool ExeDepsFix::shouldBreakDependence(MachineInstr *MI, unsigned OpIdx,
@@ -510,6 +562,7 @@ void ExeDepsFix::processDefs(MachineInstr *MI, bool Kill) {
unsigned OpNum;
unsigned Pref = TII->getUndefRegClearance(*MI, OpNum, TRI);
if (Pref) {
+ pickBestRegisterForUndef(MI, OpNum, Pref);
if (shouldBreakDependence(MI, OpNum, Pref))
UndefReads.push_back(std::make_pair(MI, OpNum));
}
OpenPOWER on IntegriCloud