LLVM  9.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 "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SparseBitVector.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineLoopInfo.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"

## Functions

INITIALIZE_PASS_BEGIN (SIFixWWMLiveness, DEBUG_TYPE, "SI fix WWM liveness", false, false) INITIALIZE_PASS_END(SIFixWWMLiveness

## Variables

DEBUG_TYPE

SI fix WWM liveness

SI fix WWM false

## 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 their def(s) 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 its def 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 do that by spotting three separate cases of registers:

1. A "then phi": the value resulting from phi elimination of a phi node at the end of an if..endif. If there is WWM code in the "then", then we make the def at the end of the "then" branch a partial def by adding an implicit use of the register.
2. A "loop exit register": a value written inside a loop but used outside the loop, where there is WWM code inside the loop (the case in the example above). We add an implicit_def of the register in the loop pre-header, and make the original def a partial def by adding an implicit use of the register.
3. A "loop exit phi": the value resulting from phi elimination of a phi node in a loop header. If there is WWM code inside the loop, then we make all defs inside the loop partial defs by adding an implicit use of the register on each one.

Note that we do not need to consider an if..else..endif phi. We only need to consider non-uniform control flow, and control flow structurization would have transformed a non-uniform if..else..endif into two if..endifs.

The analysis to detect these cases relies on a property of the MIR arising from this pass running straight after PHIElimination and before any coalescing: that any virtual register with more than one definition must be the new register added to lower a phi node by PHIElimination.

FIXME: We should detect whether a register in one of the above categories is already live at the WWM code before deciding to add the implicit uses to synthesize its liveness.

FIXME: I believe this whole scheme may be flawed due to the possibility of the register allocator doing live interval splitting.

Definition in file SIFixWWMLiveness.cpp.

## ◆ DEBUG_TYPE

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

Definition at line 88 of file SIFixWWMLiveness.cpp.

## ◆ INITIALIZE_PASS_BEGIN()

 INITIALIZE_PASS_BEGIN ( SIFixWWMLiveness , DEBUG_TYPE , "SI fix WWM liveness" , false , false )

## ◆ DEBUG_TYPE

 DEBUG_TYPE

Definition at line 143 of file SIFixWWMLiveness.cpp.

## ◆ false

 SI fix WWM false

Definition at line 143 of file SIFixWWMLiveness.cpp.

## ◆ liveness

 SI fix WWM liveness

Definition at line 143 of file SIFixWWMLiveness.cpp.