LLVM  7.0.0svn
SIFixWWMLiveness.cpp File Reference

Computations in WWM can overwrite values in inactive channels for variables that the register allocator thinks are dead. More...

#include "AMDGPU.h"
#include "AMDGPUSubtarget.h"
#include "SIInstrInfo.h"
#include "SIRegisterInfo.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
Include dependency graph for SIFixWWMLiveness.cpp:

Go to the source code of this file.

## Macros

#define DEBUG_TYPE   "si-fix-wwm-liveness"

## Detailed Description

Computations in WWM can overwrite values in inactive channels for variables that the register allocator thinks are dead.

This pass adds fake uses of those variables to WWM instructions to make sure that they aren't overwritten.

As an example, consider this snippet: vgpr0 = V_MOV_B32_e32 0.0 if (...) { vgpr1 = ... vgpr2 = WWM killed vgpr1 ... = killed vgpr2 vgpr0 = V_MOV_B32_e32 1.0 } ... = vgpr0

The live intervals of vgpr0 don't overlap with those of vgpr1. Normally, we can safely allocate vgpr0 and vgpr1 in the same register, since writing vgpr1 would only write to channels that would be clobbered by the second write to vgpr0 anyways. But if vgpr1 is written with WWM enabled, it would clobber even the inactive channels for which the if-condition is false, for which vgpr0 is supposed to be 0. This pass adds an implicit use of vgpr0 to the WWM instruction to make sure they aren't allocated to the same register.

In general, we need to figure out what registers might have their inactive channels which are eventually used accidentally clobbered by a WWM instruction. We approximate this using two conditions:

1. A definition of the variable reaches the WWM instruction.
2. The variable would be live at the WWM instruction if all its defs were partial defs (i.e. considered as a use), ignoring normal uses.

If a register matches both conditions, then we add an implicit use of it to the WWM instruction. Condition #2 is the heart of the matter: every definition is really a partial definition, since every VALU instruction is implicitly predicated. We can usually ignore this, but WWM forces us not to. Condition #1 prevents false positives if the variable is undefined at the WWM instruction anyways. This is overly conservative in certain cases, especially in uniform control flow, but this is a workaround anyways until LLVM gains the notion of predicated uses and definitions of variables.

Definition in file SIFixWWMLiveness.cpp.

## ◆ DEBUG_TYPE

 #define DEBUG_TYPE   "si-fix-wwm-liveness"

Definition at line 67 of file SIFixWWMLiveness.cpp.