blob: 93c7582dce09f69f6dcc4bd0e0df0cf09a0af454 [file] [log] [blame]
//===- DetectDeadLanes.h - SubRegister Lane Usage Analysis --*- C++ -*-----===//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/// \file
/// Analysis that tracks defined/used subregister lanes across COPY instructions
/// and instructions that get lowered to a COPY (PHI, REG_SEQUENCE,
/// The information is used to detect dead definitions and the usage of
/// (completely) undefined values and mark the operands as such.
/// This pass is necessary because the dead/undef status is not obvious anymore
/// when subregisters are involved.
/// Example:
/// %0 = some definition
/// %2 = REG_SEQUENCE %0, sub0, %1, sub1
/// %3 = EXTRACT_SUBREG %2, sub1
/// = use %3
/// The %0 definition is dead and %3 contains an undefined value.
#include "llvm/ADT/BitVector.h"
#include "llvm/MC/LaneBitmask.h"
#include <deque>
namespace llvm {
class MachineInstr;
class MachineOperand;
class MachineRegisterInfo;
class TargetRegisterInfo;
class DeadLaneDetector {
/// Contains a bitmask of which lanes of a given virtual register are
/// defined and which ones are actually used.
struct VRegInfo {
LaneBitmask UsedLanes;
LaneBitmask DefinedLanes;
DeadLaneDetector(const MachineRegisterInfo *MRI,
const TargetRegisterInfo *TRI);
/// Update the \p DefinedLanes and the \p UsedLanes for all virtual registers.
void computeSubRegisterLaneBitInfo();
const VRegInfo &getVRegInfo(unsigned RegIdx) const {
return VRegInfos[RegIdx];
bool isDefinedByCopy(unsigned RegIdx) const {
return DefinedByCopy.test(RegIdx);
/// Add used lane bits on the register used by operand \p MO. This translates
/// the bitmask based on the operands subregister, and puts the register into
/// the worklist if any new bits were added.
void addUsedLanesOnOperand(const MachineOperand &MO, LaneBitmask UsedLanes);
/// Given a bitmask \p UsedLanes for the used lanes on a def output of a
/// COPY-like instruction determine the lanes used on the use operands
/// and call addUsedLanesOnOperand() for them.
void transferUsedLanesStep(const MachineInstr &MI, LaneBitmask UsedLanes);
/// Given a use regiser operand \p Use and a mask of defined lanes, check
/// if the operand belongs to a lowersToCopies() instruction, transfer the
/// mask to the def and put the instruction into the worklist.
void transferDefinedLanesStep(const MachineOperand &Use,
LaneBitmask DefinedLanes);
/// Given a mask \p DefinedLanes of lanes defined at operand \p OpNum
/// of COPY-like instruction, determine which lanes are defined at the output
/// operand \p Def.
LaneBitmask transferDefinedLanes(const MachineOperand &Def, unsigned OpNum,
LaneBitmask DefinedLanes) const;
/// Given a mask \p UsedLanes used from the output of instruction \p MI
/// determine which lanes are used from operand \p MO of this instruction.
LaneBitmask transferUsedLanes(const MachineInstr &MI, LaneBitmask UsedLanes,
const MachineOperand &MO) const;
LaneBitmask determineInitialDefinedLanes(unsigned Reg);
LaneBitmask determineInitialUsedLanes(unsigned Reg);
const MachineRegisterInfo *MRI;
const TargetRegisterInfo *TRI;
void PutInWorklist(unsigned RegIdx) {
if (WorklistMembers.test(RegIdx))
std::unique_ptr<VRegInfo[]> VRegInfos;
/// Worklist containing virtreg indexes.
std::deque<unsigned> Worklist;
BitVector WorklistMembers;
/// This bitvector is set for each vreg index where the vreg is defined
/// by an instruction where lowersToCopies()==true.
BitVector DefinedByCopy;
} // end namespace llvm