mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-10 19:50:45 +00:00

1) Fix an issue with the incorrect value being used for the number of elements being passed to [d|w]lstp. We were trying to check that the value was available at LoopStart, but this doesn't consider that the last instruction in the block could also define the register. Two helpers have been added to RDA for this. 2) Insert some code to now try to move the element count def or the insertion point so that we can perform more tail predication. 3) Related to (1), the same off-by-one could prevent us from generating a low-overhead loop when a mov lr could have been the last instruction in the block. 4) Fix up some instruction attributes so that not all the low-overhead loop instructions are labelled as branches and terminators - as this is not true for dls/dlstp. Differential Revision: https://reviews.llvm.org/D71609
160 lines
6.1 KiB
C++
160 lines
6.1 KiB
C++
//==--- llvm/CodeGen/ReachingDefAnalysis.h - Reaching Def Analysis -*- C++ -*---==//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
/// \file Reaching Defs Analysis pass.
|
|
///
|
|
/// This pass tracks for each instruction what is the "closest" reaching def of
|
|
/// a given register. It is used by BreakFalseDeps (for clearance calculation)
|
|
/// and ExecutionDomainFix (for arbitrating conflicting domains).
|
|
///
|
|
/// Note that this is different from the usual definition notion of liveness.
|
|
/// The CPU doesn't care whether or not we consider a register killed.
|
|
///
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_REACHINGDEFSANALYSIS_H
|
|
#define LLVM_CODEGEN_REACHINGDEFSANALYSIS_H
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/CodeGen/LoopTraversal.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/InitializePasses.h"
|
|
|
|
namespace llvm {
|
|
|
|
class MachineBasicBlock;
|
|
class MachineInstr;
|
|
|
|
/// This class provides the reaching def analysis.
|
|
class ReachingDefAnalysis : public MachineFunctionPass {
|
|
private:
|
|
MachineFunction *MF;
|
|
const TargetRegisterInfo *TRI;
|
|
unsigned NumRegUnits;
|
|
/// Instruction that defined each register, relative to the beginning of the
|
|
/// current basic block. When a LiveRegsDefInfo is used to represent a
|
|
/// live-out register, this value is relative to the end of the basic block,
|
|
/// so it will be a negative number.
|
|
using LiveRegsDefInfo = std::vector<int>;
|
|
LiveRegsDefInfo LiveRegs;
|
|
|
|
/// Keeps clearance information for all registers. Note that this
|
|
/// is different from the usual definition notion of liveness. The CPU
|
|
/// doesn't care whether or not we consider a register killed.
|
|
using OutRegsInfoMap = SmallVector<LiveRegsDefInfo, 4>;
|
|
OutRegsInfoMap MBBOutRegsInfos;
|
|
|
|
/// Current instruction number.
|
|
/// The first instruction in each basic block is 0.
|
|
int CurInstr;
|
|
|
|
/// Maps instructions to their instruction Ids, relative to the begining of
|
|
/// their basic blocks.
|
|
DenseMap<MachineInstr *, int> InstIds;
|
|
|
|
/// All reaching defs of a given RegUnit for a given MBB.
|
|
using MBBRegUnitDefs = SmallVector<int, 1>;
|
|
/// All reaching defs of all reg units for a given MBB
|
|
using MBBDefsInfo = std::vector<MBBRegUnitDefs>;
|
|
/// All reaching defs of all reg units for a all MBBs
|
|
using MBBReachingDefsInfo = SmallVector<MBBDefsInfo, 4>;
|
|
MBBReachingDefsInfo MBBReachingDefs;
|
|
|
|
/// Default values are 'nothing happened a long time ago'.
|
|
const int ReachingDefDefaultVal = -(1 << 20);
|
|
|
|
public:
|
|
static char ID; // Pass identification, replacement for typeid
|
|
|
|
ReachingDefAnalysis() : MachineFunctionPass(ID) {
|
|
initializeReachingDefAnalysisPass(*PassRegistry::getPassRegistry());
|
|
}
|
|
void releaseMemory() override;
|
|
|
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
AU.setPreservesAll();
|
|
MachineFunctionPass::getAnalysisUsage(AU);
|
|
}
|
|
|
|
bool runOnMachineFunction(MachineFunction &MF) override;
|
|
|
|
MachineFunctionProperties getRequiredProperties() const override {
|
|
return MachineFunctionProperties().set(
|
|
MachineFunctionProperties::Property::NoVRegs).set(
|
|
MachineFunctionProperties::Property::TracksLiveness);
|
|
}
|
|
|
|
/// Provides the instruction id of the closest reaching def instruction of
|
|
/// PhysReg that reaches MI, relative to the begining of MI's basic block.
|
|
int getReachingDef(MachineInstr *MI, int PhysReg);
|
|
|
|
/// Provides the instruction of the closest reaching def instruction of
|
|
/// PhysReg that reaches MI, relative to the begining of MI's basic block.
|
|
MachineInstr *getReachingMIDef(MachineInstr *MI, int PhysReg);
|
|
|
|
/// Provides the MI, from the given block, corresponding to the Id or a
|
|
/// nullptr if the id does not refer to the block.
|
|
MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId);
|
|
|
|
/// Return whether A and B use the same def of PhysReg.
|
|
bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, int PhysReg);
|
|
|
|
/// Return whether the reaching def for MI also is live out of its parent
|
|
/// block.
|
|
bool isReachingDefLiveOut(MachineInstr *MI, int PhysReg);
|
|
|
|
/// Return the local MI that produces the live out value for PhysReg, or
|
|
/// nullptr for a non-live out or non-local def.
|
|
MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB,
|
|
int PhysReg);
|
|
|
|
/// Return whether the given register is used after MI, whether it's a local
|
|
/// use or a live out.
|
|
bool isRegUsedAfter(MachineInstr *MI, int PhysReg);
|
|
|
|
/// Provides the first instruction before MI that uses PhysReg
|
|
MachineInstr *getInstWithUseBefore(MachineInstr *MI, int PhysReg);
|
|
|
|
/// Provides all instructions before MI that uses PhysReg
|
|
void getAllInstWithUseBefore(MachineInstr *MI, int PhysReg,
|
|
SmallVectorImpl<MachineInstr*> &Uses);
|
|
|
|
/// Provides the clearance - the number of instructions since the closest
|
|
/// reaching def instuction of PhysReg that reaches MI.
|
|
int getClearance(MachineInstr *MI, MCPhysReg PhysReg);
|
|
|
|
/// Provides the uses, in the same block as MI, of register that MI defines.
|
|
/// This does not consider live-outs.
|
|
void getReachingLocalUses(MachineInstr *MI, int PhysReg,
|
|
SmallVectorImpl<MachineInstr*> &Uses);
|
|
|
|
/// Provide the number of uses, in the same block as MI, of the register that
|
|
/// MI defines.
|
|
unsigned getNumUses(MachineInstr *MI, int PhysReg);
|
|
|
|
private:
|
|
/// Set up LiveRegs by merging predecessor live-out values.
|
|
void enterBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
|
|
|
|
/// Update live-out values.
|
|
void leaveBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
|
|
|
|
/// Process he given basic block.
|
|
void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
|
|
|
|
/// Update def-ages for registers defined by MI.
|
|
/// Also break dependencies on partial defs and undef uses.
|
|
void processDefs(MachineInstr *);
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_CODEGEN_REACHINGDEFSANALYSIS_H
|